Module Name:    src
Committed By:   jmcneill
Date:           Mon Mar 16 21:37:35 UTC 2015

Modified Files:
        src/sys/arch/arm/amlogic: amlogic_sdhc.c

Log Message:
sdhc stability improvements


To generate a diff of this commit:
cvs rdiff -u -r1.2 -r1.3 src/sys/arch/arm/amlogic/amlogic_sdhc.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/amlogic/amlogic_sdhc.c
diff -u src/sys/arch/arm/amlogic/amlogic_sdhc.c:1.2 src/sys/arch/arm/amlogic/amlogic_sdhc.c:1.3
--- src/sys/arch/arm/amlogic/amlogic_sdhc.c:1.2	Sun Mar  8 15:38:25 2015
+++ src/sys/arch/arm/amlogic/amlogic_sdhc.c	Mon Mar 16 21:37:35 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: amlogic_sdhc.c,v 1.2 2015/03/08 15:38:25 jmcneill Exp $ */
+/* $NetBSD: amlogic_sdhc.c,v 1.3 2015/03/16 21:37:35 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2015 Jared D. McNeill <jmcne...@invisible.ca>
@@ -29,7 +29,7 @@
 #include "locators.h"
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: amlogic_sdhc.c,v 1.2 2015/03/08 15:38:25 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: amlogic_sdhc.c,v 1.3 2015/03/16 21:37:35 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -430,7 +430,7 @@ static void
 amlogic_sdhc_exec_command(sdmmc_chipset_handle_t sch, struct sdmmc_command *cmd)
 {
 	struct amlogic_sdhc_softc *sc = sch;
-	uint32_t cmdval = 0, cntl, srst, pdma;
+	uint32_t cmdval = 0, cntl, srst, pdma, ictl;
 	int i;
 
 	KASSERT(cmd->c_blklen <= 512);
@@ -446,9 +446,6 @@ amlogic_sdhc_exec_command(sdmmc_chipset_
 		goto done;
 	}
 
-	while (SDHC_READ(sc, SD_STAT_REG) & __BIT(24))
-		delay(10);
-
 	if (cmd->c_opcode == MMC_STOP_TRANSMISSION)
 		cmdval |= SD_SEND_DATA_STOP;
 	if (cmd->c_flags & SCF_RSP_PRESENT)
@@ -460,6 +457,12 @@ amlogic_sdhc_exec_command(sdmmc_chipset_
 	if ((cmd->c_flags & SCF_RSP_CRC) == 0)
 		cmdval |= SD_SEND_RESPONSE_NO_CRC;
 
+	SDHC_WRITE(sc, SD_ICTL_REG, 0);
+	SDHC_WRITE(sc, SD_ISTA_REG, SD_INT_CLEAR);
+	sc->sc_intr_ista = 0;
+
+	ictl = SD_INT_ERROR;
+
 	cntl = SDHC_READ(sc, SD_CNTL_REG);
 	cntl &= ~SD_CNTL_PACK_LEN;
 	if (cmd->c_datalen > 0) {
@@ -477,17 +480,26 @@ amlogic_sdhc_exec_command(sdmmc_chipset_
 		cntl |= __SHIFTIN(cmd->c_blklen & 0x1ff, SD_CNTL_PACK_LEN);
 				    
 		cmdval |= __SHIFTIN(nblks - 1, SD_SEND_TOTAL_PACK);
+
+		if (ISSET(cmd->c_flags, SCF_CMD_READ)) {
+			ictl |= SD_INT_DATA_COMPLETE;
+		} else {
+			ictl |= SD_INT_DMA_DONE;
+		}
+	} else {
+		ictl |= SD_INT_RESP_COMPLETE;
 	}
-	SDHC_WRITE(sc, SD_CNTL_REG, cntl);
 
-	SDHC_WRITE(sc, SD_ISTA_REG, SD_INT_CLEAR);
-	sc->sc_intr_ista = 0;
-	SDHC_WRITE(sc, SD_ICTL_REG,
-	    SD_INT_ERROR | SD_INT_DATA_COMPLETE | SD_INT_RESP_COMPLETE |
-	    SD_INT_DMA_DONE);
+	SDHC_WRITE(sc, SD_ICTL_REG, ictl);
+
+	SDHC_WRITE(sc, SD_CNTL_REG, cntl);
 
 	pdma = SDHC_READ(sc, SD_PDMA_REG);
-	pdma |= SD_PDMA_DMA_MODE;
+	if (cmd->c_datalen > 0) {
+		pdma |= SD_PDMA_DMA_MODE;
+	} else {
+		pdma &= ~SD_PDMA_DMA_MODE;
+	}
 	SDHC_WRITE(sc, SD_PDMA_REG, pdma);
 
 	SDHC_WRITE(sc, SD_ARGU_REG, cmd->c_arg);
@@ -506,7 +518,19 @@ amlogic_sdhc_exec_command(sdmmc_chipset_
 	cmd->c_resid = cmd->c_datalen;
 	SDHC_WRITE(sc, SD_SEND_REG, cmdval | cmd->c_opcode);
 
-	if (cmd->c_flags & SCF_RSP_PRESENT) {
+	if (cmd->c_datalen > 0) {
+		uint32_t wbit = ISSET(cmd->c_flags, SCF_CMD_READ) ?
+		    SD_INT_DATA_COMPLETE : SD_INT_DMA_DONE;
+		cmd->c_error = amlogic_sdhc_wait_ista(sc,
+		    SD_INT_ERROR | wbit, hz * 10);
+		if (cmd->c_error == 0 &&
+		    (sc->sc_intr_ista & SD_INT_ERROR)) {
+			cmd->c_error = ETIMEDOUT;
+		}
+		if (cmd->c_error) {
+			goto done;
+		}
+	} else {
 		cmd->c_error = amlogic_sdhc_wait_ista(sc,
 		    SD_INT_ERROR | SD_INT_RESP_COMPLETE, hz * 10);
 		if (cmd->c_error == 0 && (sc->sc_intr_ista & SD_INT_ERROR)) {
@@ -521,17 +545,7 @@ amlogic_sdhc_exec_command(sdmmc_chipset_
 		}
 	}
 
-	if (cmd->c_datalen > 0) {
-		cmd->c_error = amlogic_sdhc_wait_ista(sc,
-		    SD_INT_ERROR | SD_INT_DMA_DONE, hz * 10);
-		if (cmd->c_error == 0 &&
-		    (sc->sc_intr_ista & SD_INT_ERROR)) {
-			cmd->c_error = ETIMEDOUT;
-		}
-		if (cmd->c_error) {
-			goto done;
-		}
-	}
+	SDHC_WRITE(sc, SD_ISTA_REG, sc->sc_intr_ista);
 
 	if (cmd->c_flags & SCF_RSP_PRESENT) {
 		pdma = SDHC_READ(sc, SD_PDMA_REG);

Reply via email to