From 459e142a08b41a04e8a05449de57dcdc27f0ddff Mon Sep 17 00:00:00 2001 From: matt Date: Wed, 29 Jun 2011 06:21:16 +0000 Subject: [PATCH] Add some inital changes for the Freescale eSDHC. --- sys/dev/sdmmc/sdhc.c | 57 ++++++++++++++++++++++++++++++++--------- sys/dev/sdmmc/sdhcreg.h | 8 +++++- sys/dev/sdmmc/sdhcvar.h | 5 +++- 3 files changed, 56 insertions(+), 14 deletions(-) diff --git a/sys/dev/sdmmc/sdhc.c b/sys/dev/sdmmc/sdhc.c index 782721f4049a..9562305beda9 100644 --- a/sys/dev/sdmmc/sdhc.c +++ b/sys/dev/sdmmc/sdhc.c @@ -1,4 +1,4 @@ -/* $NetBSD: sdhc.c,v 1.8 2010/10/07 12:06:10 kiyohara Exp $ */ +/* $NetBSD: sdhc.c,v 1.9 2011/06/29 06:21:16 matt Exp $ */ /* $OpenBSD: sdhc.c,v 1.25 2009/01/13 19:44:20 grange Exp $ */ /* @@ -23,7 +23,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: sdhc.c,v 1.8 2010/10/07 12:06:10 kiyohara Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sdhc.c,v 1.9 2011/06/29 06:21:16 matt Exp $"); #include #include @@ -176,8 +176,12 @@ sdhc_host_found(struct sdhc_softc *sc, bus_space_tag_t iot, 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(">1.0/%u\n", SDHC_VENDOR_VERSION(sdhcver)); + aprint_normal(">2.0/%u\n", SDHC_VENDOR_VERSION(sdhcver)); break; } #endif @@ -227,10 +231,14 @@ sdhc_host_found(struct sdhc_softc *sc, bus_space_tag_t iot, if (SDHC_BASE_FREQ_KHZ(caps) != 0) hp->clkbase = SDHC_BASE_FREQ_KHZ(caps); if (hp->clkbase == 0) { - /* The attachment driver must tell us. */ - aprint_error_dev(sc->sc_dev, "unknown base clock frequency\n"); - goto err; - } else if (hp->clkbase < 10000 || hp->clkbase > 63000) { + if (sc->sc_clkbase == 0) { + /* The attachment driver must tell us. */ + aprint_error_dev(sc->sc_dev,"unknown base clock frequency\n"); + goto err; + } + hp->clkbase = sc->sc_clkbase; + } + if (hp->clkbase < 10000 || hp->clkbase > 10000 * 256) { /* SDHC 1.0 supports only 10-63 MHz. */ aprint_error_dev(sc->sc_dev, "base clock frequency out of range: %u MHz\n", @@ -273,6 +281,10 @@ sdhc_host_found(struct sdhc_softc *sc, bus_space_tag_t iot, hp->maxblklen = 2048; break; + case SDHC_MAX_BLK_LEN_4096: + hp->maxblklen = 4096; + break; + default: aprint_error_dev(sc->sc_dev, "max block length unknown\n"); goto err; @@ -292,6 +304,8 @@ sdhc_host_found(struct sdhc_softc *sc, bus_space_tag_t iot, saa.saa_dmat = hp->dmat; saa.saa_clkmin = hp->clkbase / 256; saa.saa_clkmax = hp->clkbase; + if (ISSET(sc->sc_flags, SDHC_FLAG_HAVE_DVS)) + saa.saa_clkmin /= 16; saa.saa_caps = SMC_CAPS_4BIT_MODE|SMC_CAPS_AUTO_STOP; #if notyet if (ISSET(hp->flags, SHF_USE_DMA)) @@ -561,9 +575,23 @@ sdhc_clock_divisor(struct sdhc_host *hp, u_int freq) { int div; - for (div = 1; div <= 256; div *= 2) - if ((hp->clkbase / div) <= freq) - return (div / 2); + if (hp->sc->sc_flags & SDHC_FLAG_HAVE_DVS) { + int dvs = (hp->clkbase + freq - 1) / freq; + div = 1; + for (div = 1; div <= 256; div <<= 1, dvs >>= 1) { + if (dvs <= 16) { + div <<= SDHC_SDCLK_DIV_SHIFT; + div |= (dvs - 1) << SDHC_SDCLK_DVS_SHIFT; + return div; + } + } + } else { + for (div = 1; div <= 256; div *= 2) { + if ((hp->clkbase / div) <= freq) + return (div / 2) << SDHC_SDCLK_DIV_SHIFT; + } + } + /* No divisor found. */ return -1; } @@ -611,7 +639,7 @@ sdhc_bus_clock(sdmmc_chipset_handle_t sch, int freq) error = EINVAL; goto out; } - HWRITE2(hp, SDHC_CLOCK_CTL, div << SDHC_SDCLK_DIV_SHIFT); + HWRITE2(hp, SDHC_CLOCK_CTL, div); /* * Start internal clock. Wait 10ms for stabilization. @@ -1199,8 +1227,13 @@ sdhc_intr(void *arg) /* * Wake up the sdmmc event thread to scan for cards. */ - if (ISSET(status, SDHC_CARD_REMOVAL|SDHC_CARD_INSERTION)) + if (ISSET(status, SDHC_CARD_REMOVAL|SDHC_CARD_INSERTION)) { sdmmc_needs_discover(hp->sdmmc); +#if 0 + HCLR2(hp, SDHC_NINTR_STATUS_EN, + status & (SDHC_CARD_REMOVAL|SDHC_CARD_INSERTION)); +#endif + } /* * Wake up the blocking process to service command diff --git a/sys/dev/sdmmc/sdhcreg.h b/sys/dev/sdmmc/sdhcreg.h index 75fa67a93808..f20879f242d8 100644 --- a/sys/dev/sdmmc/sdhcreg.h +++ b/sys/dev/sdmmc/sdhcreg.h @@ -1,4 +1,4 @@ -/* $NetBSD: sdhcreg.h,v 1.2 2011/03/17 16:56:58 matt Exp $ */ +/* $NetBSD: sdhcreg.h,v 1.3 2011/06/29 06:21:16 matt Exp $ */ /* $OpenBSD: sdhcreg.h,v 1.4 2006/07/30 17:20:40 fgsch Exp $ */ /* @@ -112,6 +112,7 @@ #define SDHC_COMMAND_COMPLETE (1<<0) #define SDHC_NINTR_STATUS_MASK 0x81ff #define SDHC_EINTR_STATUS 0x32 +#define SDHC_DMA_ERROR (1<<12) #define SDHC_AUTO_CMD12_ERROR (1<<8) #define SDHC_CURRENT_LIMIT_ERROR (1<<7) #define SDHC_DATA_END_BIT_ERROR (1<<6) @@ -147,6 +148,11 @@ #define SDHC_TIMEOUT_FREQ_SHIFT 0 #define SDHC_TIMEOUT_FREQ_MASK 0x1f #define SDHC_MAX_CAPABILITIES 0x48 +#define SDHC_HOST_VER 0xFC +#define SDHC_VVN_MASK 0x0f +#define SDHC_VVN_SHIFT 0x04 +#define SDHC_SVN_MASK 0x0f +#define SDHC_SVN_SHIFT 0x00 #define SDHC_SLOT_INTR_STATUS 0xfc #define SDHC_HOST_CTL_VERSION 0xfe #define SDHC_SPEC_VERS_SHIFT 0 diff --git a/sys/dev/sdmmc/sdhcvar.h b/sys/dev/sdmmc/sdhcvar.h index 382d0ff46661..10f03c02ec65 100644 --- a/sys/dev/sdmmc/sdhcvar.h +++ b/sys/dev/sdmmc/sdhcvar.h @@ -1,4 +1,4 @@ -/* $NetBSD: sdhcvar.h,v 1.4 2010/03/27 03:04:52 nonaka Exp $ */ +/* $NetBSD: sdhcvar.h,v 1.5 2011/06/29 06:21:16 matt Exp $ */ /* $OpenBSD: sdhcvar.h,v 1.3 2007/09/06 08:01:01 jsg Exp $ */ /* @@ -38,6 +38,9 @@ struct sdhc_softc { #define SDHC_FLAG_USE_DMA 0x0001 #define SDHC_FLAG_FORCE_DMA 0x0002 #define SDHC_FLAG_NO_PWR0 0x0004 +#define SDHC_FLAG_HAVE_DVS 0x0008 +#define SDHC_FLAG_32BIT_ACCESS 0x0010 + uint32_t sc_clkbase; }; /* Host controller functions called by the attachment driver. */