Tue Apr 6 15:55:46 2010 UTC ()
Enable DMA transfer.


(nonaka)
diff -r1.4 -r1.5 src/sys/arch/arm/xscale/pxa2x0_mci.c

cvs diff -r1.4 -r1.5 src/sys/arch/arm/xscale/pxa2x0_mci.c (expand / switch to unified diff)

--- src/sys/arch/arm/xscale/pxa2x0_mci.c 2010/03/13 12:28:44 1.4
+++ src/sys/arch/arm/xscale/pxa2x0_mci.c 2010/04/06 15:55:46 1.5
@@ -1,34 +1,34 @@ @@ -1,34 +1,34 @@
1/* $NetBSD: pxa2x0_mci.c,v 1.4 2010/03/13 12:28:44 nonaka Exp $ */ 1/* $NetBSD: pxa2x0_mci.c,v 1.5 2010/04/06 15:55:46 nonaka Exp $ */
2/* $OpenBSD: pxa2x0_mmc.c,v 1.5 2009/02/23 18:09:55 miod Exp $ */ 2/* $OpenBSD: pxa2x0_mmc.c,v 1.5 2009/02/23 18:09:55 miod Exp $ */
3 3
4/* 4/*
5 * Copyright (c) 2007 Uwe Stuehler <uwe@openbsd.org> 5 * Copyright (c) 2007 Uwe Stuehler <uwe@openbsd.org>
6 * 6 *
7 * Permission to use, copy, modify, and distribute this software for any 7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above 8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies. 9 * copyright notice and this permission notice appear in all copies.
10 * 10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 */ 18 */
19 19
20/*- 20/*-
21 * Copyright (c) 2007-2009 NONAKA Kimihiro <nonaka@netbsd.org> 21 * Copyright (c) 2007-2010 NONAKA Kimihiro <nonaka@netbsd.org>
22 * All rights reserved. 22 * All rights reserved.
23 * 23 *
24 * Redistribution and use in source and binary forms, with or without 24 * Redistribution and use in source and binary forms, with or without
25 * modification, are permitted provided that the following conditions 25 * modification, are permitted provided that the following conditions
26 * are met: 26 * are met:
27 * 1. Redistributions of source code must retain the above copyright 27 * 1. Redistributions of source code must retain the above copyright
28 * notice, this list of conditions and the following disclaimer. 28 * notice, this list of conditions and the following disclaimer.
29 * 2. Redistributions in binary form must reproduce the above copyright 29 * 2. Redistributions in binary form must reproduce the above copyright
30 * notice, this list of conditions and the following disclaimer in the 30 * notice, this list of conditions and the following disclaimer in the
31 * documentation and/or other materials provided with the distribution. 31 * documentation and/or other materials provided with the distribution.
32 * 32 *
33 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 33 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
34 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 34 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
@@ -44,63 +44,63 @@ @@ -44,63 +44,63 @@
44 */ 44 */
45 45
46/* 46/*
47 * MMC/SD/SDIO controller driver for Intel PXA2xx processors 47 * MMC/SD/SDIO controller driver for Intel PXA2xx processors
48 * 48 *
49 * Power management is beyond control of the processor's SD/SDIO/MMC 49 * Power management is beyond control of the processor's SD/SDIO/MMC
50 * block, so this driver depends on the attachment driver to provide 50 * block, so this driver depends on the attachment driver to provide
51 * us with some callback functions via the "tag" member in our softc. 51 * us with some callback functions via the "tag" member in our softc.
52 * Bus power management calls are then dispatched to the attachment 52 * Bus power management calls are then dispatched to the attachment
53 * driver. 53 * driver.
54 */ 54 */
55 55
56#include <sys/cdefs.h> 56#include <sys/cdefs.h>
57__KERNEL_RCSID(0, "$NetBSD: pxa2x0_mci.c,v 1.4 2010/03/13 12:28:44 nonaka Exp $"); 57__KERNEL_RCSID(0, "$NetBSD: pxa2x0_mci.c,v 1.5 2010/04/06 15:55:46 nonaka Exp $");
58 58
59#include <sys/param.h> 59#include <sys/param.h>
60#include <sys/device.h> 60#include <sys/device.h>
61#include <sys/systm.h> 61#include <sys/systm.h>
62#include <sys/malloc.h> 62#include <sys/malloc.h>
63#include <sys/kernel.h> 63#include <sys/kernel.h>
64#include <sys/proc.h> 64#include <sys/proc.h>
65#include <sys/bus.h> 65#include <sys/bus.h>
66#include <sys/mutex.h> 66#include <sys/mutex.h>
67#include <sys/condvar.h> 67#include <sys/condvar.h>
68 68
69#include <machine/intr.h> 69#include <machine/intr.h>
70 70
71#include <dev/sdmmc/sdmmcvar.h> 71#include <dev/sdmmc/sdmmcvar.h>
72#include <dev/sdmmc/sdmmcchip.h> 72#include <dev/sdmmc/sdmmcchip.h>
73 73
74#include <arm/xscale/pxa2x0cpu.h> 74#include <arm/xscale/pxa2x0cpu.h>
75#include <arm/xscale/pxa2x0reg.h> 75#include <arm/xscale/pxa2x0reg.h>
76#include <arm/xscale/pxa2x0var.h> 76#include <arm/xscale/pxa2x0var.h>
77#include <arm/xscale/pxa2x0_dmac.h> 77#include <arm/xscale/pxa2x0_dmac.h>
78#include <arm/xscale/pxa2x0_gpio.h> 78#include <arm/xscale/pxa2x0_gpio.h>
79#include <arm/xscale/pxa2x0_mci.h> 79#include <arm/xscale/pxa2x0_mci.h>
80 80
81#ifdef PXAMCI_DEBUG 81#ifdef PXAMCI_DEBUG
82int pxamci_debug = 1; 82int pxamci_debug = 9;
83#define DPRINTF(n,s) do { if ((n) <= pxamci_debug) printf s; } while (0) 83#define DPRINTF(n,s) do { if ((n) <= pxamci_debug) printf s; } while (0)
84#else 84#else
85#define DPRINTF(n,s) do {} while (0) 85#define DPRINTF(n,s) do {} while (0)
86#endif 86#endif
87 87
88#ifndef DEBUG 88#ifndef PXAMCI_DEBUG
89#define STOPCLK_TIMO 2 /* ms */ 89#define STOPCLK_TIMO 2 /* sec */
90#define EXECCMD_TIMO 2 /* ms */ 90#define EXECCMD_TIMO 2 /* sec */
91#else 91#else
92#define STOPCLK_TIMO 2 /* ms */ 92#define STOPCLK_TIMO 2 /* sec */
93#define EXECCMD_TIMO 5 /* ms */ 93#define EXECCMD_TIMO 5 /* sec */
94#endif 94#endif
95 95
96static int pxamci_host_reset(sdmmc_chipset_handle_t); 96static int pxamci_host_reset(sdmmc_chipset_handle_t);
97static uint32_t pxamci_host_ocr(sdmmc_chipset_handle_t); 97static uint32_t pxamci_host_ocr(sdmmc_chipset_handle_t);
98static int pxamci_host_maxblklen(sdmmc_chipset_handle_t); 98static int pxamci_host_maxblklen(sdmmc_chipset_handle_t);
99static int pxamci_card_detect(sdmmc_chipset_handle_t); 99static int pxamci_card_detect(sdmmc_chipset_handle_t);
100static int pxamci_write_protect(sdmmc_chipset_handle_t); 100static int pxamci_write_protect(sdmmc_chipset_handle_t);
101static int pxamci_bus_power(sdmmc_chipset_handle_t, uint32_t); 101static int pxamci_bus_power(sdmmc_chipset_handle_t, uint32_t);
102static int pxamci_bus_clock(sdmmc_chipset_handle_t, int); 102static int pxamci_bus_clock(sdmmc_chipset_handle_t, int);
103static int pxamci_bus_width(sdmmc_chipset_handle_t, int); 103static int pxamci_bus_width(sdmmc_chipset_handle_t, int);
104static void pxamci_exec_command(sdmmc_chipset_handle_t, 104static void pxamci_exec_command(sdmmc_chipset_handle_t,
105 struct sdmmc_command *); 105 struct sdmmc_command *);
106static void pxamci_card_enable_intr(sdmmc_chipset_handle_t, int); 106static void pxamci_card_enable_intr(sdmmc_chipset_handle_t, int);
@@ -145,26 +145,34 @@ static void pxamci_stop_clock(struct pxa @@ -145,26 +145,34 @@ static void pxamci_stop_clock(struct pxa
145#define CSR_READ_1(sc, reg) \ 145#define CSR_READ_1(sc, reg) \
146 bus_space_read_1((sc)->sc_iot, (sc)->sc_ioh, (reg)) 146 bus_space_read_1((sc)->sc_iot, (sc)->sc_ioh, (reg))
147#define CSR_WRITE_1(sc, reg, val) \ 147#define CSR_WRITE_1(sc, reg, val) \
148 bus_space_write_1((sc)->sc_iot, (sc)->sc_ioh, (reg), (val)) 148 bus_space_write_1((sc)->sc_iot, (sc)->sc_ioh, (reg), (val))
149#define CSR_READ_4(sc, reg) \ 149#define CSR_READ_4(sc, reg) \
150 bus_space_read_4((sc)->sc_iot, (sc)->sc_ioh, (reg)) 150 bus_space_read_4((sc)->sc_iot, (sc)->sc_ioh, (reg))
151#define CSR_WRITE_4(sc, reg, val) \ 151#define CSR_WRITE_4(sc, reg, val) \
152 bus_space_write_4((sc)->sc_iot, (sc)->sc_ioh, (reg), (val)) 152 bus_space_write_4((sc)->sc_iot, (sc)->sc_ioh, (reg), (val))
153#define CSR_SET_4(sc, reg, val) \ 153#define CSR_SET_4(sc, reg, val) \
154 CSR_WRITE_4(sc, reg, CSR_READ_4(sc, reg) | (val)) 154 CSR_WRITE_4(sc, reg, CSR_READ_4(sc, reg) | (val))
155#define CSR_CLR_4(sc, reg, val) \ 155#define CSR_CLR_4(sc, reg, val) \
156 CSR_WRITE_4(sc, reg, CSR_READ_4(sc, reg) & ~(val)) 156 CSR_WRITE_4(sc, reg, CSR_READ_4(sc, reg) & ~(val))
157 157
 158#if 0 /* XXX */
 159#define DMA_ALIGNED(addr) \
 160 (((u_long)(addr) & 0x7) == 0 || !CPU_IS_PXA250)
 161#else
 162#define DMA_ALIGNED(addr) \
 163 (((u_long)(addr) & 0x1f) == 0)
 164#endif
 165
158static void 166static void
159pxamci_enable_intr(struct pxamci_softc *sc, uint32_t mask) 167pxamci_enable_intr(struct pxamci_softc *sc, uint32_t mask)
160{ 168{
161 int s; 169 int s;
162 170
163 s = splsdmmc(); 171 s = splsdmmc();
164 sc->sc_imask &= ~mask; 172 sc->sc_imask &= ~mask;
165 CSR_WRITE_4(sc, MMC_I_MASK, sc->sc_imask); 173 CSR_WRITE_4(sc, MMC_I_MASK, sc->sc_imask);
166 splx(s); 174 splx(s);
167} 175}
168 176
169static void 177static void
170pxamci_disable_intr(struct pxamci_softc *sc, uint32_t mask) 178pxamci_disable_intr(struct pxamci_softc *sc, uint32_t mask)
@@ -228,29 +236,26 @@ pxamci_attach_sub(device_t self, struct  @@ -228,29 +236,26 @@ pxamci_attach_sub(device_t self, struct
228 pxamci_bus_clock(sc, sc->sc_clkbase); 236 pxamci_bus_clock(sc, sc->sc_clkbase);
229 237
230 /* Setup max block length */ 238 /* Setup max block length */
231 if (CPU_IS_PXA270) { 239 if (CPU_IS_PXA270) {
232 sc->sc_maxblklen = 2048; 240 sc->sc_maxblklen = 2048;
233 } else { 241 } else {
234 sc->sc_maxblklen = 512; 242 sc->sc_maxblklen = 512;
235 } 243 }
236 244
237 /* Set default bus width */ 245 /* Set default bus width */
238 sc->sc_buswidth = 1; 246 sc->sc_buswidth = 1;
239 247
240 /* setting DMA */ 248 /* setting DMA */
241#if 1 /* XXX */ 
242 SET(sc->sc_caps, PMC_CAPS_NO_DMA); /* disable DMA */ 
243#endif 
244 if (!ISSET(sc->sc_caps, PMC_CAPS_NO_DMA)) { 249 if (!ISSET(sc->sc_caps, PMC_CAPS_NO_DMA)) {
245 aprint_normal_dev(sc->sc_dev, "using DMA transfer\n"); 250 aprint_normal_dev(sc->sc_dev, "using DMA transfer\n");
246 251
247 sc->sc_rxdr.ds_addr = PXA2X0_MMC_BASE + MMC_RXFIFO; 252 sc->sc_rxdr.ds_addr = PXA2X0_MMC_BASE + MMC_RXFIFO;
248 sc->sc_rxdr.ds_len = 1; 253 sc->sc_rxdr.ds_len = 1;
249 sc->sc_rxdx = pxa2x0_dmac_allocate_xfer(M_NOWAIT); 254 sc->sc_rxdx = pxa2x0_dmac_allocate_xfer(M_NOWAIT);
250 if (sc->sc_rxdx == NULL) { 255 if (sc->sc_rxdx == NULL) {
251 aprint_error_dev(sc->sc_dev, 256 aprint_error_dev(sc->sc_dev,
252 "couldn't alloc rx dma xfer\n"); 257 "couldn't alloc rx dma xfer\n");
253 goto free_intr; 258 goto free_intr;
254 } 259 }
255 sc->sc_rxdx->dx_cookie = sc; 260 sc->sc_rxdx->dx_cookie = sc;
256 sc->sc_rxdx->dx_priority = DMAC_PRIORITY_NORMAL; 261 sc->sc_rxdx->dx_priority = DMAC_PRIORITY_NORMAL;
@@ -291,30 +296,28 @@ pxamci_attach_sub(device_t self, struct  @@ -291,30 +296,28 @@ pxamci_attach_sub(device_t self, struct
291 * Attach the generic SD/MMC bus driver. (The bus driver must 296 * Attach the generic SD/MMC bus driver. (The bus driver must
292 * not invoke any chipset functions before it is attached.) 297 * not invoke any chipset functions before it is attached.)
293 */ 298 */
294 memset(&saa, 0, sizeof(saa)); 299 memset(&saa, 0, sizeof(saa));
295 saa.saa_busname = "sdmmc"; 300 saa.saa_busname = "sdmmc";
296 saa.saa_sct = &pxamci_chip_functions; 301 saa.saa_sct = &pxamci_chip_functions;
297 saa.saa_sch = sc; 302 saa.saa_sch = sc;
298 saa.saa_dmat = pxa->pxa_dmat; 303 saa.saa_dmat = pxa->pxa_dmat;
299 saa.saa_clkmin = sc->sc_clkmin; 304 saa.saa_clkmin = sc->sc_clkmin;
300 saa.saa_clkmax = sc->sc_clkmax; 305 saa.saa_clkmax = sc->sc_clkmax;
301 saa.saa_caps = 0; 306 saa.saa_caps = 0;
302 if (!ISSET(sc->sc_caps, PMC_CAPS_NO_DMA)) 307 if (!ISSET(sc->sc_caps, PMC_CAPS_NO_DMA))
303 SET(saa.saa_caps, SMC_CAPS_DMA); 308 SET(saa.saa_caps, SMC_CAPS_DMA);
304#if notyet 
305 if (CPU_IS_PXA270 && ISSET(sc->sc_caps, PMC_CAPS_4BIT)) 309 if (CPU_IS_PXA270 && ISSET(sc->sc_caps, PMC_CAPS_4BIT))
306 SET(saa.saa_caps, SMC_CAPS_4BIT_MODE); 310 SET(saa.saa_caps, SMC_CAPS_4BIT_MODE);
307#endif 
308 311
309 sc->sc_sdmmc = config_found(sc->sc_dev, &saa, NULL); 312 sc->sc_sdmmc = config_found(sc->sc_dev, &saa, NULL);
310 if (sc->sc_sdmmc == NULL) { 313 if (sc->sc_sdmmc == NULL) {
311 aprint_error_dev(sc->sc_dev, "couldn't attach bus\n"); 314 aprint_error_dev(sc->sc_dev, "couldn't attach bus\n");
312 goto free_xfer; 315 goto free_xfer;
313 } 316 }
314 return 0; 317 return 0;
315 318
316free_xfer: 319free_xfer:
317 if (!ISSET(sc->sc_caps, PMC_CAPS_NO_DMA)) { 320 if (!ISSET(sc->sc_caps, PMC_CAPS_NO_DMA)) {
318 if (sc->sc_rxdx) 321 if (sc->sc_rxdx)
319 pxa2x0_dmac_free_xfer(sc->sc_rxdx); 322 pxa2x0_dmac_free_xfer(sc->sc_rxdx);
320 if (sc->sc_txdx) 323 if (sc->sc_txdx)
@@ -602,55 +605,60 @@ pxamci_exec_command(sdmmc_chipset_handle @@ -602,55 +605,60 @@ pxamci_exec_command(sdmmc_chipset_handle
602 if (numblk > NOB_MASK) { 605 if (numblk > NOB_MASK) {
603 aprint_error_dev(sc->sc_dev, "too much data\n"); 606 aprint_error_dev(sc->sc_dev, "too much data\n");
604 cmd->c_error = EINVAL; 607 cmd->c_error = EINVAL;
605 goto out; 608 goto out;
606 } 609 }
607 610
608 CSR_WRITE_4(sc, MMC_BLKLEN, blklen); 611 CSR_WRITE_4(sc, MMC_BLKLEN, blklen);
609 CSR_WRITE_4(sc, MMC_NOB, numblk); 612 CSR_WRITE_4(sc, MMC_NOB, numblk);
610 CSR_WRITE_4(sc, MMC_RDTO, RDTO_MASK); 613 CSR_WRITE_4(sc, MMC_RDTO, RDTO_MASK);
611 614
612 cmdat |= CMDAT_DATA_EN; 615 cmdat |= CMDAT_DATA_EN;
613 616
614 /* setting DMA */ 617 /* setting DMA */
615 if (!ISSET(sc->sc_caps, PMC_CAPS_NO_DMA)) { 618 if (!ISSET(sc->sc_caps, PMC_CAPS_NO_DMA)
 619 && DMA_ALIGNED(cmd->c_data)) {
616 struct dmac_xfer_desc *dx_desc; 620 struct dmac_xfer_desc *dx_desc;
617 621
 622 DPRINTF(1,("%s: using DMA\n",device_xname(sc->sc_dev)));
 623
618 cmdat |= CMDAT_MMC_DMA_EN; 624 cmdat |= CMDAT_MMC_DMA_EN;
619 625
620 if (ISSET(cmd->c_flags, SCF_CMD_READ)) { 626 if (ISSET(cmd->c_flags, SCF_CMD_READ)) {
621 dx_desc = &sc->sc_rxdx->dx_desc[DMAC_DESC_DST]; 627 dx_desc = &sc->sc_rxdx->dx_desc[DMAC_DESC_DST];
622 dx_desc->xd_nsegs = cmd->c_dmamap->dm_nsegs; 628 dx_desc->xd_nsegs = cmd->c_dmamap->dm_nsegs;
623 dx_desc->xd_dma_segs = cmd->c_dmamap->dm_segs; 629 dx_desc->xd_dma_segs = cmd->c_dmamap->dm_segs;
624 error = pxa2x0_dmac_start_xfer(sc->sc_rxdx); 630 error = pxa2x0_dmac_start_xfer(sc->sc_rxdx);
625 } else { 631 } else {
626 dx_desc = &sc->sc_txdx->dx_desc[DMAC_DESC_SRC]; 632 dx_desc = &sc->sc_txdx->dx_desc[DMAC_DESC_SRC];
627 dx_desc->xd_nsegs = cmd->c_dmamap->dm_nsegs; 633 dx_desc->xd_nsegs = cmd->c_dmamap->dm_nsegs;
628 dx_desc->xd_dma_segs = cmd->c_dmamap->dm_segs; 634 dx_desc->xd_dma_segs = cmd->c_dmamap->dm_segs;
629 /* workaround for erratum #91 */ 635 /* workaround for erratum #91 */
630 error = 0; 636 error = 0;
631 if (!CPU_IS_PXA270) { 637 if (!CPU_IS_PXA270) {
632 error = 638 error =
633 pxa2x0_dmac_start_xfer(sc->sc_txdx); 639 pxa2x0_dmac_start_xfer(sc->sc_txdx);
634 } 640 }
635 } 641 }
636 if (error) { 642 if (error) {
637 aprint_error_dev(sc->sc_dev, 643 aprint_error_dev(sc->sc_dev,
638 "couldn't start dma xfer. (error=%d)\n", 644 "couldn't start dma xfer. (error=%d)\n",
639 error); 645 error);
640 cmd->c_error = EIO; 646 cmd->c_error = EIO;
641 goto err; 647 goto err;
642 } 648 }
643 } else { 649 } else {
 650 DPRINTF(1,("%s: using PIO\n",device_xname(sc->sc_dev)));
 651
644 cmd->c_resid = cmd->c_datalen; 652 cmd->c_resid = cmd->c_datalen;
645 cmd->c_buf = cmd->c_data; 653 cmd->c_buf = cmd->c_data;
646 654
647 pxamci_enable_intr(sc, MMC_I_RXFIFO_RD_REQ 655 pxamci_enable_intr(sc, MMC_I_RXFIFO_RD_REQ
648 | MMC_I_TXFIFO_WR_REQ 656 | MMC_I_TXFIFO_WR_REQ
649 | MMC_I_DAT_ERR); 657 | MMC_I_DAT_ERR);
650 } 658 }
651 } 659 }
652 660
653 sc->sc_cmd = cmd; 661 sc->sc_cmd = cmd;
654 662
655 /* 663 /*
656 * "After reset, the MMC card must be initialized by sending 664 * "After reset, the MMC card must be initialized by sending
@@ -729,50 +737,51 @@ pxamci_stop_clock(struct pxamci_softc *s @@ -729,50 +737,51 @@ pxamci_stop_clock(struct pxamci_softc *s
729 * SD/MMC controller interrput handler 737 * SD/MMC controller interrput handler
730 */ 738 */
731static int 739static int
732pxamci_intr(void *arg) 740pxamci_intr(void *arg)
733{ 741{
734 struct pxamci_softc *sc = arg; 742 struct pxamci_softc *sc = arg;
735 int status; 743 int status;
736#ifdef PXAMCI_DEBUG 744#ifdef PXAMCI_DEBUG
737 int ostatus; 745 int ostatus;
738 746
739 ostatus = 747 ostatus =
740#endif 748#endif
741 status = CSR_READ_4(sc, MMC_I_REG) & ~CSR_READ_4(sc, MMC_I_MASK); 749 status = CSR_READ_4(sc, MMC_I_REG) & ~CSR_READ_4(sc, MMC_I_MASK);
742 DPRINTF(9,("%s: intr status = %08x\n", device_xname(sc->sc_dev), 750 DPRINTF(10,("%s: intr status = %08x\n", device_xname(sc->sc_dev),
743 status)); 751 status));
744 752
745 /* 753 /*
746 * Notify the process waiting in pxamci_clock_stop() when 754 * Notify the process waiting in pxamci_clock_stop() when
747 * the clock has really stopped. 755 * the clock has really stopped.
748 */ 756 */
749 if (ISSET(status, MMC_I_CLK_IS_OFF)) { 757 if (ISSET(status, MMC_I_CLK_IS_OFF)) {
750 DPRINTF(2,("%s: clock is now off\n", device_xname(sc->sc_dev))); 758 DPRINTF(2,("%s: clock is now off\n", device_xname(sc->sc_dev)));
751 wakeup(sc); 759 wakeup(sc);
752 pxamci_disable_intr(sc, MMC_I_CLK_IS_OFF); 760 pxamci_disable_intr(sc, MMC_I_CLK_IS_OFF);
753 CLR(status, MMC_I_CLK_IS_OFF); 761 CLR(status, MMC_I_CLK_IS_OFF);
754 } 762 }
755 763
756 if (sc->sc_cmd == NULL) 764 if (sc->sc_cmd == NULL)
757 goto end; 765 goto end;
758 766
759 if (ISSET(status, MMC_I_RES_ERR)) { 767 if (ISSET(status, MMC_I_RES_ERR)) {
760 DPRINTF(9, ("%s: handling MMC_I_RES_ERR\n", 768 DPRINTF(9, ("%s: handling MMC_I_RES_ERR\n",
761 device_xname(sc->sc_dev))); 769 device_xname(sc->sc_dev)));
762 pxamci_disable_intr(sc, MMC_I_RES_ERR); 770 pxamci_disable_intr(sc, MMC_I_RES_ERR);
763 CLR(status, MMC_I_RES_ERR|MMC_I_END_CMD_RES); 771 CLR(status, MMC_I_RES_ERR|MMC_I_END_CMD_RES);
764 if (!ISSET(sc->sc_caps, PMC_CAPS_NO_DMA) 772 if (!ISSET(sc->sc_caps, PMC_CAPS_NO_DMA)
765 && (sc->sc_cmd->c_datalen > 0)) { 773 && (sc->sc_cmd->c_datalen > 0)
 774 && DMA_ALIGNED(sc->sc_cmd->c_data)) {
766 if (ISSET(sc->sc_cmd->c_flags, SCF_CMD_READ)) { 775 if (ISSET(sc->sc_cmd->c_flags, SCF_CMD_READ)) {
767 pxa2x0_dmac_abort_xfer(sc->sc_rxdx); 776 pxa2x0_dmac_abort_xfer(sc->sc_rxdx);
768 } else { 777 } else {
769 pxa2x0_dmac_abort_xfer(sc->sc_txdx); 778 pxa2x0_dmac_abort_xfer(sc->sc_txdx);
770 } 779 }
771 } 780 }
772 sc->sc_cmd->c_error = ENOEXEC; 781 sc->sc_cmd->c_error = ENOEXEC;
773 pxamci_intr_done(sc); 782 pxamci_intr_done(sc);
774 goto end; 783 goto end;
775 } 784 }
776 785
777 if (ISSET(status, MMC_I_END_CMD_RES)) { 786 if (ISSET(status, MMC_I_END_CMD_RES)) {
778 DPRINTF(9,("%s: handling MMC_I_END_CMD_RES\n", 787 DPRINTF(9,("%s: handling MMC_I_END_CMD_RES\n",
@@ -786,51 +795,52 @@ pxamci_intr(void *arg) @@ -786,51 +795,52 @@ pxamci_intr(void *arg)
786 CLR(status, MMC_I_PRG_DONE); 795 CLR(status, MMC_I_PRG_DONE);
787 } 796 }
788 if (sc->sc_cmd == NULL) 797 if (sc->sc_cmd == NULL)
789 goto end; 798 goto end;
790 } 799 }
791 800
792 if (ISSET(status, MMC_I_DAT_ERR)) { 801 if (ISSET(status, MMC_I_DAT_ERR)) {
793 DPRINTF(9, ("%s: handling MMC_I_DAT_ERR\n", 802 DPRINTF(9, ("%s: handling MMC_I_DAT_ERR\n",
794 device_xname(sc->sc_dev))); 803 device_xname(sc->sc_dev)));
795 sc->sc_cmd->c_error = EIO; 804 sc->sc_cmd->c_error = EIO;
796 pxamci_intr_done(sc); 805 pxamci_intr_done(sc);
797 pxamci_disable_intr(sc, MMC_I_DAT_ERR); 806 pxamci_disable_intr(sc, MMC_I_DAT_ERR);
798 CLR(status, MMC_I_DAT_ERR); 807 CLR(status, MMC_I_DAT_ERR);
799 if (!ISSET(sc->sc_caps, PMC_CAPS_NO_DMA)) { 808 if (!ISSET(sc->sc_caps, PMC_CAPS_NO_DMA)
 809 && DMA_ALIGNED(sc->sc_cmd->c_data)) {
800 if (ISSET(sc->sc_cmd->c_flags, SCF_CMD_READ)) { 810 if (ISSET(sc->sc_cmd->c_flags, SCF_CMD_READ)) {
801 pxa2x0_dmac_abort_xfer(sc->sc_rxdx); 811 pxa2x0_dmac_abort_xfer(sc->sc_rxdx);
802 } else { 812 } else {
803 pxa2x0_dmac_abort_xfer(sc->sc_txdx); 813 pxa2x0_dmac_abort_xfer(sc->sc_txdx);
804 } 814 }
805 } 815 }
806 /* ignore transmission done condition */ 816 /* ignore transmission done condition */
807 if (ISSET(status, MMC_I_DATA_TRAN_DONE)) { 817 if (ISSET(status, MMC_I_DATA_TRAN_DONE)) {
808 pxamci_disable_intr(sc, MMC_I_DATA_TRAN_DONE); 818 pxamci_disable_intr(sc, MMC_I_DATA_TRAN_DONE);
809 CLR(status, MMC_I_DATA_TRAN_DONE); 819 CLR(status, MMC_I_DATA_TRAN_DONE);
810 } 820 }
811 goto end; 821 goto end;
812 } 822 }
813 823
814 if (ISSET(status, MMC_I_DATA_TRAN_DONE)) { 824 if (ISSET(status, MMC_I_DATA_TRAN_DONE)) {
815 DPRINTF(9,("%s: handling MMC_I_DATA_TRAN_DONE\n", 825 DPRINTF(9,("%s: handling MMC_I_DATA_TRAN_DONE\n",
816 device_xname(sc->sc_dev))); 826 device_xname(sc->sc_dev)));
817 pxamci_intr_done(sc); 827 pxamci_intr_done(sc);
818 pxamci_disable_intr(sc, MMC_I_DATA_TRAN_DONE); 828 pxamci_disable_intr(sc, MMC_I_DATA_TRAN_DONE);
819 CLR(status, MMC_I_DATA_TRAN_DONE); 829 CLR(status, MMC_I_DATA_TRAN_DONE);
820 } 830 }
821 831
822 if (ISSET(status, MMC_I_TXFIFO_WR_REQ|MMC_I_RXFIFO_RD_REQ)) { 832 if (ISSET(status, MMC_I_TXFIFO_WR_REQ|MMC_I_RXFIFO_RD_REQ)) {
823 DPRINTF(9,("%s: handling MMC_I_xxFIFO_xx_REQ\n", 833 DPRINTF(10,("%s: handling MMC_I_xxFIFO_xx_REQ\n",
824 device_xname(sc->sc_dev))); 834 device_xname(sc->sc_dev)));
825 pxamci_intr_data(sc); 835 pxamci_intr_data(sc);
826 CLR(status, MMC_I_TXFIFO_WR_REQ|MMC_I_RXFIFO_RD_REQ); 836 CLR(status, MMC_I_TXFIFO_WR_REQ|MMC_I_RXFIFO_RD_REQ);
827 } 837 }
828 838
829 if (ISSET(status, STAT_SDIO_INT)) { 839 if (ISSET(status, STAT_SDIO_INT)) {
830 DPRINTF(9,("%s: handling STAT_SDIO_INT\n", 840 DPRINTF(9,("%s: handling STAT_SDIO_INT\n",
831 device_xname(sc->sc_dev))); 841 device_xname(sc->sc_dev)));
832 sdmmc_card_intr(sc->sc_sdmmc); 842 sdmmc_card_intr(sc->sc_sdmmc);
833 CLR(status, STAT_SDIO_INT); 843 CLR(status, STAT_SDIO_INT);
834 } 844 }
835 845
836end: 846end:
@@ -910,55 +920,57 @@ pxamci_intr_cmd(struct pxamci_softc *sc) @@ -910,55 +920,57 @@ pxamci_intr_cmd(struct pxamci_softc *sc)
910 && ISSET(cmd->c_flags, SCF_RSP_CRC) 920 && ISSET(cmd->c_flags, SCF_RSP_CRC)
911 && CPU_IS_PXA270) { 921 && CPU_IS_PXA270) {
912 /* workaround for erratum #42 */ 922 /* workaround for erratum #42 */
913 if (ISSET(cmd->c_flags, SCF_RSP_136) 923 if (ISSET(cmd->c_flags, SCF_RSP_136)
914 && (cmd->c_resp[0] & 0x80000000U)) { 924 && (cmd->c_resp[0] & 0x80000000U)) {
915 DPRINTF(1,("%s: ignore CRC error\n", 925 DPRINTF(1,("%s: ignore CRC error\n",
916 device_xname(sc->sc_dev))); 926 device_xname(sc->sc_dev)));
917 } else 927 } else
918 cmd->c_error = EIO; 928 cmd->c_error = EIO;
919 } else if (ISSET(status, STAT_ERR)) 929 } else if (ISSET(status, STAT_ERR))
920 cmd->c_error = EIO; 930 cmd->c_error = EIO;
921 931
922 if (cmd->c_error == 0 && cmd->c_datalen > 0) { 932 if (cmd->c_error == 0 && cmd->c_datalen > 0) {
923 /* workaround for erratum #91 */ 
924 if (!ISSET(sc->sc_caps, PMC_CAPS_NO_DMA) 933 if (!ISSET(sc->sc_caps, PMC_CAPS_NO_DMA)
925 && CPU_IS_PXA270 934 && DMA_ALIGNED(cmd->c_data)) {
926 && !ISSET(cmd->c_flags, SCF_CMD_READ)) { 935 /* workaround for erratum #91 */
927 error = pxa2x0_dmac_start_xfer(sc->sc_txdx); 936 if (CPU_IS_PXA270
928 if (error) { 937 && !ISSET(cmd->c_flags, SCF_CMD_READ)) {
929 aprint_error_dev(sc->sc_dev, 938 error = pxa2x0_dmac_start_xfer(sc->sc_txdx);
930 "couldn't start dma xfer. (error=%d)\n", 939 if (error) {
931 error); 940 aprint_error_dev(sc->sc_dev,
932 cmd->c_error = EIO; 941 "couldn't start dma xfer."
933 pxamci_intr_done(sc); 942 " (error=%d)\n", error);
934 return; 943 cmd->c_error = EIO;
 944 pxamci_intr_done(sc);
 945 return;
 946 }
935 } 947 }
936 pxamci_enable_intr(sc, 948 pxamci_enable_intr(sc,
937 MMC_I_DATA_TRAN_DONE|MMC_I_DAT_ERR); 949 MMC_I_DATA_TRAN_DONE|MMC_I_DAT_ERR);
938 } 950 }
939 } else { 951 } else {
940 pxamci_intr_done(sc); 952 pxamci_intr_done(sc);
941 } 953 }
942} 954}
943 955
944static void 956static void
945pxamci_intr_data(struct pxamci_softc *sc) 957pxamci_intr_data(struct pxamci_softc *sc)
946{ 958{
947 struct sdmmc_command *cmd = sc->sc_cmd; 959 struct sdmmc_command *cmd = sc->sc_cmd;
948 int intr; 960 int intr;
949 int n; 961 int n;
950 962
951 DPRINTF(1,("%s: pxamci_intr_data: cmd = %p, resid = %d\n", 963 DPRINTF(10,("%s: pxamci_intr_data: cmd = %p, resid = %d\n",
952 device_xname(sc->sc_dev), cmd, cmd->c_resid)); 964 device_xname(sc->sc_dev), cmd, cmd->c_resid));
953 965
954 n = MIN(32, cmd->c_resid); 966 n = MIN(32, cmd->c_resid);
955 cmd->c_resid -= n; 967 cmd->c_resid -= n;
956 968
957 if (ISSET(cmd->c_flags, SCF_CMD_READ)) { 969 if (ISSET(cmd->c_flags, SCF_CMD_READ)) {
958 intr = MMC_I_RXFIFO_RD_REQ; 970 intr = MMC_I_RXFIFO_RD_REQ;
959 while (n-- > 0) 971 while (n-- > 0)
960 *cmd->c_buf++ = CSR_READ_1(sc, MMC_RXFIFO); 972 *cmd->c_buf++ = CSR_READ_1(sc, MMC_RXFIFO);
961 } else { 973 } else {
962 int short_xfer = n < 32; 974 int short_xfer = n < 32;
963 975
964 intr = MMC_I_TXFIFO_WR_REQ; 976 intr = MMC_I_TXFIFO_WR_REQ;
@@ -988,29 +1000,39 @@ pxamci_intr_done(struct pxamci_softc *sc @@ -988,29 +1000,39 @@ pxamci_intr_done(struct pxamci_softc *sc
988 1000
989 pxamci_disable_intr(sc, MMC_I_TXFIFO_WR_REQ|MMC_I_RXFIFO_RD_REQ| 1001 pxamci_disable_intr(sc, MMC_I_TXFIFO_WR_REQ|MMC_I_RXFIFO_RD_REQ|
990 MMC_I_DATA_TRAN_DONE|MMC_I_END_CMD_RES|MMC_I_RES_ERR|MMC_I_DAT_ERR); 1002 MMC_I_DATA_TRAN_DONE|MMC_I_END_CMD_RES|MMC_I_RES_ERR|MMC_I_DAT_ERR);
991 SET(sc->sc_cmd->c_flags, SCF_ITSDONE); 1003 SET(sc->sc_cmd->c_flags, SCF_ITSDONE);
992 sc->sc_cmd = NULL; 1004 sc->sc_cmd = NULL;
993 wakeup(sc); 1005 wakeup(sc);
994} 1006}
995 1007
996static void 1008static void
997pxamci_dmac_iintr(struct dmac_xfer *dx, int status) 1009pxamci_dmac_iintr(struct dmac_xfer *dx, int status)
998{ 1010{
999 struct pxamci_softc *sc = dx->dx_cookie; 1011 struct pxamci_softc *sc = dx->dx_cookie;
1000 1012
 1013 DPRINTF(1,("%s: pxamci_dmac_iintr: status = %#x\n",
 1014 device_xname(sc->sc_dev), status));
 1015
1001 if (status) { 1016 if (status) {
1002 aprint_error_dev(sc->sc_dev, "pxamci_dmac_iintr: " 1017 aprint_error_dev(sc->sc_dev, "pxamci_dmac_iintr: "
1003 "non-zero completion status %d\n", status); 1018 "non-zero completion status %d\n", status);
1004 } 1019 }
1005} 1020}
1006 1021
1007static void 1022static void
1008pxamci_dmac_ointr(struct dmac_xfer *dx, int status) 1023pxamci_dmac_ointr(struct dmac_xfer *dx, int status)
1009{ 1024{
1010 struct pxamci_softc *sc = dx->dx_cookie; 1025 struct pxamci_softc *sc = dx->dx_cookie;
1011 1026
1012 if (status) { 1027 DPRINTF(1,("%s: pxamci_dmac_ointr: status = %#x\n",
 1028 device_xname(sc->sc_dev), status));
 1029
 1030 if (status == 0) {
 1031 if (sc->sc_cmd != NULL && (sc->sc_cmd->c_datalen & 31) != 0) {
 1032 CSR_WRITE_4(sc, MMC_PRTBUF, 1);
 1033 }
 1034 } else {
1013 aprint_error_dev(sc->sc_dev, "pxamci_dmac_ointr: " 1035 aprint_error_dev(sc->sc_dev, "pxamci_dmac_ointr: "
1014 "non-zero completion status %d\n", status); 1036 "non-zero completion status %d\n", status);
1015 } 1037 }
1016} 1038}