CVS commit: [netbsd-6] src/sys/dev/sdmmc

2013-01-02 Thread Jeff Rizzo
Module Name:src
Committed By:   riz
Date:   Wed Jan  2 23:34:56 UTC 2013

Modified Files:
src/sys/dev/sdmmc [netbsd-6]: sdhc.c sdhcreg.h

Log Message:
sys/dev/sdmmc/sdhc.cpatch
sys/dev/sdmmc/sdhcreg.h patch

Support SDHC version 3 clocks.
[skrll, ticket #759]


To generate a diff of this commit:
cvs rdiff -u -r1.10.2.3 -r1.10.2.4 src/sys/dev/sdmmc/sdhc.c
cvs rdiff -u -r1.5.2.1 -r1.5.2.2 src/sys/dev/sdmmc/sdhcreg.h

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

Modified files:

Index: src/sys/dev/sdmmc/sdhc.c
diff -u src/sys/dev/sdmmc/sdhc.c:1.10.2.3 src/sys/dev/sdmmc/sdhc.c:1.10.2.4
--- src/sys/dev/sdmmc/sdhc.c:1.10.2.3	Thu Aug  9 06:36:48 2012
+++ src/sys/dev/sdmmc/sdhc.c	Wed Jan  2 23:34:56 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: sdhc.c,v 1.10.2.3 2012/08/09 06:36:48 jdc Exp $	*/
+/*	$NetBSD: sdhc.c,v 1.10.2.4 2013/01/02 23:34:56 riz Exp $	*/
 /*	$OpenBSD: sdhc.c,v 1.25 2009/01/13 19:44:20 grange Exp $	*/
 
 /*
@@ -23,7 +23,7 @@
  */
 
 #include sys/cdefs.h
-__KERNEL_RCSID(0, $NetBSD: sdhc.c,v 1.10.2.3 2012/08/09 06:36:48 jdc Exp $);
+__KERNEL_RCSID(0, $NetBSD: sdhc.c,v 1.10.2.4 2013/01/02 23:34:56 riz Exp $);
 
 #ifdef _KERNEL_OPT
 #include opt_sdmmc.h
@@ -79,6 +79,8 @@ struct sdhc_host {
 	struct kmutex intr_mtx;
 	struct kcondvar intr_cv;
 
+	int specver;			/* spec. version */
+
 	uint32_t flags;			/* flags for this host */
 #define SHF_USE_DMA		0x0001
 #define SHF_USE_4BIT_MODE	0x0002
@@ -223,26 +225,8 @@ sdhc_host_found(struct sdhc_softc *sc, b
 	struct sdmmcbus_attach_args saa;
 	struct sdhc_host *hp;
 	uint32_t caps;
-#ifdef SDHC_DEBUG
 	uint16_t sdhcver;
 
-	sdhcver = bus_space_read_2(iot, ioh, SDHC_HOST_CTL_VERSION);
-	aprint_normal_dev(sc-sc_dev, SD Host Specification/Vendor Version );
-	switch (SDHC_SPEC_VERSION(sdhcver)) {
-	case 0x00:
-		aprint_normal(1.0/%u\n, SDHC_VENDOR_VERSION(sdhcver));
-		break;
-
-	case 0x01:
-		aprint_normal(2.0/%u\n, SDHC_VENDOR_VERSION(sdhcver));
-		break;
-
-	default:
-		aprint_normal(2.0/%u\n, SDHC_VENDOR_VERSION(sdhcver));
-		break;
-	}
-#endif
-
 	/* Allocate one more host structure. */
 	hp = malloc(sizeof(struct sdhc_host), M_DEVBUF, M_WAITOK|M_ZERO);
 	if (hp == NULL) {
@@ -262,6 +246,29 @@ sdhc_host_found(struct sdhc_softc *sc, b
 	mutex_init(hp-intr_mtx, MUTEX_DEFAULT, IPL_SDMMC);
 	cv_init(hp-intr_cv, sdhcintr);
 
+	sdhcver = HREAD2(hp, SDHC_HOST_CTL_VERSION);
+	aprint_normal_dev(sc-sc_dev, SD Host Specification );
+	hp-specver = SDHC_SPEC_VERSION(sdhcver);
+	switch (SDHC_SPEC_VERSION(sdhcver)) {
+	case SDHC_SPEC_VERS_100:
+		aprint_normal(1.0);
+		break;
+
+	case SDHC_SPEC_VERS_200:
+		aprint_normal(2.0);
+		break;
+
+	case SDHC_SPEC_VERS_300:
+		aprint_normal(3.0);
+		break;
+
+	default:
+		aprint_normal(unknown version(0x%x),
+		SDHC_SPEC_VERSION(sdhcver));
+		break;
+	}
+	aprint_normal(, rev.%u\n, SDHC_VENDOR_VERSION(sdhcver));
+
 	/*
 	 * Reset the host controller and enable interrupts.
 	 */
@@ -289,8 +296,11 @@ sdhc_host_found(struct sdhc_softc *sc, b
 	/*
 	 * Determine the base clock frequency. (2.2.24)
 	 */
-	if (SDHC_BASE_FREQ_KHZ(caps) != 0)
+	if (hp-specver == SDHC_SPEC_VERS_300) {
+		hp-clkbase = SDHC_BASE_V3_FREQ_KHZ(caps);
+	} else {
 		hp-clkbase = SDHC_BASE_FREQ_KHZ(caps);
+	}
 	if (hp-clkbase == 0) {
 		if (sc-sc_clkbase == 0) {
 			/* The attachment driver must tell us. */
@@ -370,12 +380,16 @@ sdhc_host_found(struct sdhc_softc *sc, b
 	saa.saa_sct = sdhc_functions;
 	saa.saa_sch = hp;
 	saa.saa_dmat = hp-dmat;
-	saa.saa_clkmin = hp-clkbase / 256;
 	saa.saa_clkmax = hp-clkbase;
 	if (ISSET(sc-sc_flags, SDHC_FLAG_HAVE_CGM))
-		saa.saa_clkmin /= 2046;
+		saa.saa_clkmin = hp-clkbase / 256 / 2046;
 	else if (ISSET(sc-sc_flags, SDHC_FLAG_HAVE_DVS))
-		saa.saa_clkmin /= 16;
+		saa.saa_clkmin = hp-clkbase / 256 / 16;
+	else if (hp-specver == SDHC_SPEC_VERS_300)
+		saa.saa_clkmin = hp-clkbase / 0x3ff;
+	else
+		saa.saa_clkmin = hp-clkbase / 256;
+
 	saa.saa_caps = SMC_CAPS_4BIT_MODE|SMC_CAPS_AUTO_STOP;
 	if (ISSET(sc-sc_flags, SDHC_FLAG_8BIT_MODE))
 		saa.saa_caps |= SMC_CAPS_8BIT_MODE;
@@ -725,16 +739,29 @@ sdhc_clock_divisor(struct sdhc_host *hp,
 			 */
 			roundup |= dvs  1;
 		}
-		panic(%s: can't find divisor for freq %u, HDEVNAME(hp), freq);
+		/* No divisor found. */
+		return false;
+	}
+	if (hp-specver == SDHC_SPEC_VERS_300) {
+		div = howmany(hp-clkbase, freq);
+		if (div  0x3ff)
+			return false;
+		*divp = (((div  8)  SDHC_SDCLK_XDIV_MASK)
+			  SDHC_SDCLK_XDIV_SHIFT) |
+			(((div  0)  SDHC_SDCLK_DIV_MASK)
+			  SDHC_SDCLK_DIV_SHIFT);
+		return true;
 	} else {
 		for (div = 1; div = 256; div *= 2) {
 			if ((hp-clkbase / div) = freq) {
 *divp = (div / 2)  SDHC_SDCLK_DIV_SHIFT;
+//freq = hp-clkbase / div;
 return true;
 			}
 		}
+		/* No divisor found. */
+		return false;
 	}
-
 	/* No divisor found. */
 	return false;
 }

Index: src/sys/dev/sdmmc/sdhcreg.h
diff -u 

CVS commit: [netbsd-6] src/sys/dev/sdmmc

2013-01-02 Thread Jeff Rizzo
Module Name:src
Committed By:   riz
Date:   Wed Jan  2 23:34:56 UTC 2013

Modified Files:
src/sys/dev/sdmmc [netbsd-6]: sdhc.c sdhcreg.h

Log Message:
sys/dev/sdmmc/sdhc.cpatch
sys/dev/sdmmc/sdhcreg.h patch

Support SDHC version 3 clocks.
[skrll, ticket #759]


To generate a diff of this commit:
cvs rdiff -u -r1.10.2.3 -r1.10.2.4 src/sys/dev/sdmmc/sdhc.c
cvs rdiff -u -r1.5.2.1 -r1.5.2.2 src/sys/dev/sdmmc/sdhcreg.h

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



CVS commit: [netbsd-6] src/sys/dev/sdmmc

2012-08-08 Thread Julian Coleman
Module Name:src
Committed By:   jdc
Date:   Wed Aug  8 06:19:00 UTC 2012

Modified Files:
src/sys/dev/sdmmc [netbsd-6]: sdhc.c sdhcreg.h sdmmc_mem.c sdmmcreg.h

Log Message:
Pull up revisions:
  src/sys/dev/sdmmc/sdhc.c revisions 1.16,1.20,1.21,1.22,1.23 via patch,1.25
  src/sys/dev/sdmmc/sdhcreg.h revision 1.8
  src/sys/dev/sdmmc/sdmmc_mem.c revisions 1.21,1.22
  src/sys/dev/sdmmc/sdmmcreg.h revisions 1.10,1.11,1.12
(requested by matt in ticket 441).

SDHCI byte swaps the BE response on the wire into LE registers.
As we always want response data in LE, use bus_space_read_stream.
Additonally, read response data in 1 or 4 4-byte chunks, instead of
one 4-byte chunk or 15 1-byte chunks.

bus_space_*_stream_N() functions are not universally available.
Provite alternate implementation for when they are unavailable.

Handle interrupt acknowledgement in the SDHC_FLAG_32BIT_ACCESS case in
the same way as non-SDHC_FLAG_32BIT_ACCESS case.

If there was an error in 32-bit mode, just set ERROR_INTERRUPT otherwise
see if matched anything we care about.

Add use of watermark register when PIO to an ESDHC.  After every kill or
drain of watermask words, pause a bit to give time for the fifo to recover.
Always the command response in BE byteorder.  Rewrite __bitfield to deal
with this.

Responses are actually in host order (except SCR which is return in
big endian so that's convert to host order).

Fix comments about __bitfield.


To generate a diff of this commit:
cvs rdiff -u -r1.10.2.1 -r1.10.2.2 src/sys/dev/sdmmc/sdhc.c
cvs rdiff -u -r1.5 -r1.5.2.1 src/sys/dev/sdmmc/sdhcreg.h
cvs rdiff -u -r1.20 -r1.20.2.1 src/sys/dev/sdmmc/sdmmc_mem.c
cvs rdiff -u -r1.8 -r1.8.2.1 src/sys/dev/sdmmc/sdmmcreg.h

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

Modified files:

Index: src/sys/dev/sdmmc/sdhc.c
diff -u src/sys/dev/sdmmc/sdhc.c:1.10.2.1 src/sys/dev/sdmmc/sdhc.c:1.10.2.2
--- src/sys/dev/sdmmc/sdhc.c:1.10.2.1	Mon Jun 11 17:45:32 2012
+++ src/sys/dev/sdmmc/sdhc.c	Wed Aug  8 06:18:59 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: sdhc.c,v 1.10.2.1 2012/06/11 17:45:32 riz Exp $	*/
+/*	$NetBSD: sdhc.c,v 1.10.2.2 2012/08/08 06:18:59 jdc Exp $	*/
 /*	$OpenBSD: sdhc.c,v 1.25 2009/01/13 19:44:20 grange Exp $	*/
 
 /*
@@ -23,7 +23,7 @@
  */
 
 #include sys/cdefs.h
-__KERNEL_RCSID(0, $NetBSD: sdhc.c,v 1.10.2.1 2012/06/11 17:45:32 riz Exp $);
+__KERNEL_RCSID(0, $NetBSD: sdhc.c,v 1.10.2.2 2012/08/08 06:18:59 jdc Exp $);
 
 #ifdef _KERNEL_OPT
 #include opt_sdmmc.h
@@ -987,14 +987,11 @@ sdhc_exec_command(sdmmc_chipset_handle_t
 	 */
 	mutex_enter(hp-host_mtx);
 	if (cmd-c_error == 0  ISSET(cmd-c_flags, SCF_RSP_PRESENT)) {
+		cmd-c_resp[0] = HREAD4(hp, SDHC_RESPONSE + 0);
 		if (ISSET(cmd-c_flags, SCF_RSP_136)) {
-			uint8_t *p = (uint8_t *)cmd-c_resp;
-			int i;
-
-			for (i = 0; i  15; i++)
-*p++ = HREAD1(hp, SDHC_RESPONSE + i);
-		} else {
-			cmd-c_resp[0] = HREAD4(hp, SDHC_RESPONSE);
+			cmd-c_resp[1] = HREAD4(hp, SDHC_RESPONSE + 4);
+			cmd-c_resp[2] = HREAD4(hp, SDHC_RESPONSE + 8);
+			cmd-c_resp[3] = HREAD4(hp, SDHC_RESPONSE + 12);
 		}
 	}
 	mutex_exit(hp-host_mtx);
@@ -1379,17 +1376,33 @@ static void
 esdhc_read_data_pio(struct sdhc_host *hp, uint8_t *data, u_int datalen)
 {
 	uint16_t status = HREAD2(hp, SDHC_NINTR_STATUS);
+	uint32_t v;
+
+	const size_t watermark = (HREAD4(hp, SDHC_WATERMARK_LEVEL)  SDHC_WATERMARK_READ_SHIFT)  SDHC_WATERMARK_READ_MASK;
+	size_t count = 0;
+
 	while (datalen  3  !ISSET(status, SDHC_TRANSFER_COMPLETE)) {
-		uint32_t v = HREAD4(hp, SDHC_DATA);
+		if (count == 0) {
+			/*
+			 * If we've drained watermark words, we need to wait
+			 * a little bit so the read FIFO can refill.
+			 */
+			sdmmc_delay(10);
+			count = watermark;
+		}
+		v = HREAD4(hp, SDHC_DATA);
 		v = le32toh(v);
 		*(uint32_t *)data = v;
 		data += 4;
 		datalen -= 4;
 		status = HREAD2(hp, SDHC_NINTR_STATUS);
+		count--;
 	}
-
 	if (datalen  0  !ISSET(status, SDHC_TRANSFER_COMPLETE)) {
-		uint32_t v = HREAD4(hp, SDHC_DATA);
+		if (count == 0) {
+			sdmmc_delay(10);
+		}
+		v = HREAD4(hp, SDHC_DATA);
 		v = le32toh(v);
 		do {
 			*data++ = v;
@@ -1402,16 +1415,29 @@ static void
 esdhc_write_data_pio(struct sdhc_host *hp, uint8_t *data, u_int datalen)
 {
 	uint16_t status = HREAD2(hp, SDHC_NINTR_STATUS);
+	uint32_t v;
+
+	const size_t watermark = (HREAD4(hp, SDHC_WATERMARK_LEVEL)  SDHC_WATERMARK_WRITE_SHIFT)  SDHC_WATERMARK_WRITE_MASK;
+	size_t count = watermark;
+
 	while (datalen  3  !ISSET(status, SDHC_TRANSFER_COMPLETE)) {
-		uint32_t v = *(uint32_t *)data;
+		if (count == 0) {
+			sdmmc_delay(10);
+			count = watermark;
+		}
+		v = *(uint32_t *)data;
 		v = htole32(v);
 		HWRITE4(hp, SDHC_DATA, v);
 		data += 4;
 		datalen -= 4;
 		status = HREAD2(hp, SDHC_NINTR_STATUS);
+		count--;
 	}
 	if (datalen  0  !ISSET(status, SDHC_TRANSFER_COMPLETE)) {
-		uint32_t v = *(uint32_t *)data;
+		if (count == 0) {
+			sdmmc_delay(10);
+		}
+		v = *(uint32_t *)data;
 		

CVS commit: [netbsd-6] src/sys/dev/sdmmc

2012-08-08 Thread Julian Coleman
Module Name:src
Committed By:   jdc
Date:   Wed Aug  8 06:19:00 UTC 2012

Modified Files:
src/sys/dev/sdmmc [netbsd-6]: sdhc.c sdhcreg.h sdmmc_mem.c sdmmcreg.h

Log Message:
Pull up revisions:
  src/sys/dev/sdmmc/sdhc.c revisions 1.16,1.20,1.21,1.22,1.23 via patch,1.25
  src/sys/dev/sdmmc/sdhcreg.h revision 1.8
  src/sys/dev/sdmmc/sdmmc_mem.c revisions 1.21,1.22
  src/sys/dev/sdmmc/sdmmcreg.h revisions 1.10,1.11,1.12
(requested by matt in ticket 441).

SDHCI byte swaps the BE response on the wire into LE registers.
As we always want response data in LE, use bus_space_read_stream.
Additonally, read response data in 1 or 4 4-byte chunks, instead of
one 4-byte chunk or 15 1-byte chunks.

bus_space_*_stream_N() functions are not universally available.
Provite alternate implementation for when they are unavailable.

Handle interrupt acknowledgement in the SDHC_FLAG_32BIT_ACCESS case in
the same way as non-SDHC_FLAG_32BIT_ACCESS case.

If there was an error in 32-bit mode, just set ERROR_INTERRUPT otherwise
see if matched anything we care about.

Add use of watermark register when PIO to an ESDHC.  After every kill or
drain of watermask words, pause a bit to give time for the fifo to recover.
Always the command response in BE byteorder.  Rewrite __bitfield to deal
with this.

Responses are actually in host order (except SCR which is return in
big endian so that's convert to host order).

Fix comments about __bitfield.


To generate a diff of this commit:
cvs rdiff -u -r1.10.2.1 -r1.10.2.2 src/sys/dev/sdmmc/sdhc.c
cvs rdiff -u -r1.5 -r1.5.2.1 src/sys/dev/sdmmc/sdhcreg.h
cvs rdiff -u -r1.20 -r1.20.2.1 src/sys/dev/sdmmc/sdmmc_mem.c
cvs rdiff -u -r1.8 -r1.8.2.1 src/sys/dev/sdmmc/sdmmcreg.h

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