Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/sdmmc Fix high capacity (> 2GB) eMMC support, from O...



details:   https://anonhg.NetBSD.org/src/rev/ffcd4420c9cb
branches:  trunk
changeset: 804949:ffcd4420c9cb
user:      jmcneill <jmcneill%NetBSD.org@localhost>
date:      Sun Dec 07 20:07:25 2014 +0000

description:
Fix high capacity (> 2GB) eMMC support, from OpenBSD.

diffstat:

 sys/dev/sdmmc/sdmmc_mem.c |  37 +++++++++++++++++++++++--------------
 sys/dev/sdmmc/sdmmcreg.h  |   3 ++-
 2 files changed, 25 insertions(+), 15 deletions(-)

diffs (106 lines):

diff -r ec1ca6c4468f -r ffcd4420c9cb sys/dev/sdmmc/sdmmc_mem.c
--- a/sys/dev/sdmmc/sdmmc_mem.c Sun Dec 07 18:34:24 2014 +0000
+++ b/sys/dev/sdmmc/sdmmc_mem.c Sun Dec 07 20:07:25 2014 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: sdmmc_mem.c,v 1.31 2014/03/19 15:26:42 nonaka Exp $    */
+/*     $NetBSD: sdmmc_mem.c,v 1.32 2014/12/07 20:07:25 jmcneill Exp $  */
 /*     $OpenBSD: sdmmc_mem.c,v 1.10 2009/01/09 10:55:22 jsg Exp $      */
 
 /*
@@ -45,7 +45,7 @@
 /* Routines for SD/MMC memory cards. */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sdmmc_mem.c,v 1.31 2014/03/19 15:26:42 nonaka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sdmmc_mem.c,v 1.32 2014/12/07 20:07:25 jmcneill Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_sdmmc.h"
@@ -171,6 +171,9 @@
        /* Tell the card(s) to enter the idle state (again). */
        sdmmc_go_idle_state(sc);
 
+       DPRINTF(("%s: host_ocr 0x%08x\n", SDMMCDEVNAME(sc), host_ocr));
+       DPRINTF(("%s: card_ocr 0x%08x\n", SDMMCDEVNAME(sc), card_ocr));
+
        host_ocr &= card_ocr; /* only allow the common voltages */
        if (!ISSET(sc->sc_caps, SMC_CAPS_SPI_MODE)) {
                /* Check SD Ver.2 */
@@ -493,6 +496,9 @@
 
        /* Don't lock */
 
+       DPRINTF(("%s: sdmmc_mem_send_op_cond: ocr=%#x\n",
+           SDMMCDEVNAME(sc), ocr));
+
        /*
         * If we change the OCR value, retry the command until the OCR
         * we receive in response has the "CARD BUSY" bit set, meaning
@@ -719,6 +725,7 @@
 {
        int width, value, hs_timing, bus_clock, error;
        char ext_csd[512];
+       uint32_t sectors = 0;
 
        /* change bus clock */
        bus_clock = min(sc->sc_busclk, sf->csd.tran_speed);
@@ -743,21 +750,14 @@
                                ext_csd[EXT_CSD_STRUCTURE]);
                        return error;
                }
-               hs_timing = 0;
-               switch (ext_csd[EXT_CSD_CARD_TYPE]) {
-               case EXT_CSD_CARD_TYPE_26M:
-                       sf->csd.tran_speed = 26000;     /* 26MHz */
-                       break;
 
-               case EXT_CSD_CARD_TYPE_52M:
-               case EXT_CSD_CARD_TYPE_52M_V18:
-               case EXT_CSD_CARD_TYPE_52M_V12:
-               case EXT_CSD_CARD_TYPE_52M_V12_18:
+               if (ext_csd[EXT_CSD_CARD_TYPE] & EXT_CSD_CARD_TYPE_F_52M) {
                        sf->csd.tran_speed = 52000;     /* 52MHz */
                        hs_timing = 1;
-                       break;
-
-               default:
+               } else if (ext_csd[EXT_CSD_CARD_TYPE] & EXT_CSD_CARD_TYPE_F_26M) {
+                       sf->csd.tran_speed = 26000;     /* 26MHz */
+                       hs_timing = 0;
+               } else {
                        aprint_error_dev(sc->sc_dev,
                            "unknown CARD_TYPE: 0x%x\n",
                            ext_csd[EXT_CSD_CARD_TYPE]);
@@ -804,6 +804,15 @@
                        }
                }
 
+               sectors = ext_csd[EXT_CSD_SEC_COUNT + 0] << 0 |
+                   ext_csd[EXT_CSD_SEC_COUNT + 1] << 8  |
+                   ext_csd[EXT_CSD_SEC_COUNT + 2] << 16 |
+                   ext_csd[EXT_CSD_SEC_COUNT + 3] << 24;
+               if (sectors > (2u * 1024 * 1024 * 1024) / 512) {
+                       SET(sf->flags, SFF_SDHC);
+                       sf->csd.capacity = sectors;
+               }
+
                if (ISSET(sc->sc_caps, SMC_CAPS_8BIT_MODE)) {
                        width = 8;
                        value = EXT_CSD_BUS_WIDTH_8;
diff -r ec1ca6c4468f -r ffcd4420c9cb sys/dev/sdmmc/sdmmcreg.h
--- a/sys/dev/sdmmc/sdmmcreg.h  Sun Dec 07 18:34:24 2014 +0000
+++ b/sys/dev/sdmmc/sdmmcreg.h  Sun Dec 07 20:07:25 2014 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: sdmmcreg.h,v 1.14 2013/05/03 16:38:35 matt Exp $       */
+/*     $NetBSD: sdmmcreg.h,v 1.15 2014/12/07 20:07:25 jmcneill Exp $   */
 /*     $OpenBSD: sdmmcreg.h,v 1.4 2009/01/09 10:55:22 jsg Exp $        */
 
 /*
@@ -115,6 +115,7 @@
 #define EXT_CSD_REV                    192     /* RO */
 #define EXT_CSD_STRUCTURE              194     /* RO */
 #define EXT_CSD_CARD_TYPE              196     /* RO */
+#define EXT_CSD_SEC_COUNT              212     /* RO */
 
 /* EXT_CSD field definitions */
 #define EXT_CSD_CMD_SET_NORMAL         (1U << 0)



Home | Main Index | Thread Index | Old Index