]> Zhao Yanbai Git Server - minix.git/commitdiff
eMMC: add support to 8-bit mode. 38/3038/1
authorLeonardo Fogel <leonardofogel@yahoo.com.br>
Thu, 2 Jul 2015 21:45:04 +0000 (18:45 -0300)
committerDavid van Moolenbroek <david@minix3.org>
Sun, 26 Jul 2015 15:53:37 +0000 (15:53 +0000)
Change-Id: I0470130eb5f8de319cd55c448a9aa1b9131e8e07

etc/system.conf
minix/drivers/storage/mmc/emmc.c
minix/drivers/storage/mmc/emmc.txt

index 75d77c8062a42b64f0e20e921a93411a1de7a388..15f37ff1f18ff753569276556994d5f9b1ba7f9d 100644 (file)
@@ -742,6 +742,7 @@ service emmc
        system
                PRIVCTL
                IRQCTL
+               PADCONF
        ;
        irq
                28      # MMCSD1INT
index a693f9b8acf50c79675bb8b2bf0d157d0ec3eccd..f52715f55fc82520a2f2f122bba9d016c8921a33 100644 (file)
 /* The card sector size is 512B. */
 #define SEC_SIZE 512
 
+/*
+ * AM335x Control Module registers CONF_GPMC_ADn.
+ * Configuration do multiplex CONF_GPMC_ADn to signals MMC1_DATn (Mode 1).
+ */
+#define CONF_GPMC_AD(N)  (0x800 + 4*(N))
+#define CONF_GPMC_AD_MASK 0x7F
+#define CONF_GPMC_AD_VAL  0x31
+
 /* AM335x MMC1 memory map (physical start address and size). */
 #define AM335X_MMC1_BASE_ADDR 0x481D8000
 #define AM335X_MMC1_SIZE (4 << 10)
 /* AM335x MMC1 interrupt number. */
 #define AM335X_MMCSD1INT 28
 
+static uint32_t bus_width;
+
 /* AM335x MMCHS registers virtual addresses: virtual base + offset. */
 static struct omap_mmchs_registers *reg;
 
@@ -439,8 +449,8 @@ read_busy(void)
 {
        uint32_t stat;
        /*
-        * The busy signal is optional, but the host controller will assert 
-        * SD_STAT[1] TC even if the card does not send it. 
+        * The busy signal is optional, but the host controller will assert
+        * SD_STAT[1] TC even if the card does not send it.
         */
        if (irq_wait() < 0)
                return -1;
@@ -619,6 +629,24 @@ minix_init(void)
        return 0;
 }
 
+/*
+ * Configure the Control Module registers CONF_GPMC_AD4-7.
+ * Multiplex pins GPMC_AD4-7 to signals MMC1_DAT4-7 (Mode 1).
+ * Return 0 on success, a negative integer on error.
+ */
+static int
+conf_gpmc_ad(void)
+{
+       uint32_t i;
+
+       for (i=4; i<8; i++) {
+               if (sys_padconf(CONF_GPMC_AD(i), CONF_GPMC_AD_MASK,
+                       CONF_GPMC_AD_VAL) != OK)
+                       return -1;
+       }
+       return 0;
+}
+
 /*
  * Interface to the MINIX block device driver.
  * Host controller initialization.
@@ -638,6 +666,16 @@ emmc_host_init(struct mmc_host *host)
        if (minix_init() < 0)
                return -1;
 
+       /*
+        * Multiplex pins GPMC_AD4-7 to signals MMC1_DAT4-7 (Mode 1), in order
+        * to allow the use of 8-bit mode.
+        * U-Boot multiplexes only pins GPMC_AD0-3 to signals MMC1_DAT0-3.
+        */
+       if (conf_gpmc_ad() < 0)
+               bus_width = EXT_CSD_BUS_WIDTH_4;
+       else
+               bus_width = EXT_CSD_BUS_WIDTH_8;
+
        /* Reset the host controller. */
        set32(reg->SYSCONFIG, MMCHS_SD_SYSCONFIG_SOFTRESET,
                MMCHS_SD_SYSCONFIG_SOFTRESET);
@@ -676,7 +714,7 @@ emmc_host_init(struct mmc_host *host)
 
        /* Enable the bus clock. */
        set32(reg->SYSCTL, MMCHS_SD_SYSCTL_CEN, MMCHS_SD_SYSCTL_CEN_EN);
-       
+
        /*
         * Set the internal clock gating strategy to automatic, and enable
         * Smart Idle mode. The host controller does not implement wake-up
@@ -810,7 +848,7 @@ emmc_card_initialize(struct sd_slot *slot)
        /* Card capacity for densities greater than 2GB. */
        if (MMC_EXT_CSD_SEC_COUNT > 0)
                card_size = (uint64_t)MMC_EXT_CSD_SEC_COUNT * SEC_SIZE;
-       
+
        /* CMD6. Switch to high-speed mode: EXT_CSD[185] HS_TIMING = 1. */
        if (mmc_switch(MMC_SWITCH_MODE_WRITE_BYTE, EXT_CSD_HS_TIMING, 1) < 0)
                return NULL;
@@ -832,9 +870,9 @@ emmc_card_initialize(struct sd_slot *slot)
        /* Set data and busy time-out: ~ 2,8s @ 48MHz.*/
        set32(reg->SYSCTL, MMCHS_SD_SYSCTL_DTO, MMCHS_SD_SYSCTL_DTO_2POW27);
 
-       /* CMD6. Set data bus width to 4. */
+       /* CMD6. Set data bus width. */
        if (mmc_switch(MMC_SWITCH_MODE_WRITE_BYTE, EXT_CSD_BUS_WIDTH,
-               EXT_CSD_BUS_WIDTH_4) < 0)
+               bus_width) < 0)
                return NULL;
        /* Wait for the (optional) busy signal. */
        if (read_busy() < 0)
@@ -843,8 +881,11 @@ emmc_card_initialize(struct sd_slot *slot)
        if (send_status() < 0)
                return NULL;
 
-       /* Host controller: set 4-bit data bus width. */
-       set32(reg->HCTL, MMCHS_SD_HCTL_DTW, MMCHS_SD_HCTL_DTW_4BIT);
+       /* Host controller: set data bus width. */
+       if (bus_width == EXT_CSD_BUS_WIDTH_4)
+               set32(reg->HCTL, MMCHS_SD_HCTL_DTW, MMCHS_SD_HCTL_DTW_4BIT);
+       else
+               set32(reg->CON, MMCHS_SD_CON_DW8, MMCHS_SD_CON_DW8_8BITS);
 
        /* CMD16. Set block length to sector size (512B). */
        if (set_blocklen() < 0)
index e1ba41456c8ae1dceb4150ada24d88b925f8fb6c..59c37a5932fdabbb7977e8b6999d5f67369a8dab 100644 (file)
@@ -1,17 +1,18 @@
-The eMMC driver was designed to be linked to the existing MMC/SD block device driver (mmcblk.c).
+The eMMC driver was designed to be linked to the existing MMC/SD block device
+driver (mmcblk.c).
 
 * Mini how-to
-On the BeagleBone Black, the block device files /dev/c1d* (major = 8) are free. The driver can use /dev/c1d0.
+On the BeagleBone Black, the block device files /dev/c1d* (major = 8) are free.
+The driver can use /dev/c1d0.
 # service up /service/emmc -dev /dev/c1d0
 
-* 4-bit mode (data bus width)
-On the BeagleBone Black, the eMMC data lines are connected to the AM335x GPMC_AD[0-7] pins. After PoR, these pins are multiplexed to signals GPIO1_[0-7], and U-Boot only multiplexes pins GPMC_AD[0-3] to signals MMC1_DAT[0-3]. Consequently, 8-bit mode (signals MMC1_DAT[4-7]) can not be used.
-
 * Programmed Input/Output
 The driver does not have support for DMA.
 
 * High capacity cards
-Data address for media =< 2GB is byte address, and data address for media > 2GB is sector (512B) address. The driver was designed to handle both address modes, but it was tested on a 2GB card.
+Data address for media =< 2GB is byte address, and data address for media > 2GB
+is sector (512B) address. The driver was designed to handle both address modes,
+but it was tested on a 2GB card.
 
 * References
 BeagleBone Black System Reference Manual, Revision A5.6.