drivers: mmc: Fix some issues with MMC stack
authorTien Hock, Loh <tien.hock.loh@intel.com>
Thu, 7 Mar 2019 03:34:20 +0000 (11:34 +0800)
committerTien Hock, Loh <tien.hock.loh@intel.com>
Thu, 7 Mar 2019 03:34:20 +0000 (11:34 +0800)
Some bugs in MMC stack needs to be fixed:
- scr cannot be local as this will cause cache issue when invalidating
after the read DMA transfer is completed
- ACMD41 needs to send voltage information in initialization, otherwise the
command is a query, thus will not initialize the controller
- when checking device state, retry until the retries counter goes to zero
before failing

Signed-off-by: Tien Hock, Loh <tien.hock.loh@intel.com>
drivers/mmc/mmc.c
include/drivers/mmc.h

index 77d683c459d4660180f314bbfaf879a4d2aefeb6..db6f3f9e47b9edbf189aba3b7db5c348ab8fb4b8 100644 (file)
@@ -29,6 +29,7 @@ static unsigned char mmc_ext_csd[512] __aligned(16);
 static unsigned int mmc_flags;
 static struct mmc_device_info *mmc_dev_info;
 static unsigned int rca;
+static unsigned int scr[2]__aligned(16) = { 0 };
 
 static const unsigned char tran_speed_base[16] = {
        0, 10, 12, 13, 15, 20, 26, 30, 35, 40, 45, 52, 55, 60, 70, 80
@@ -90,7 +91,8 @@ static int mmc_device_state(void)
                ret = mmc_send_cmd(MMC_CMD(13), rca << RCA_SHIFT_OFFSET,
                                   MMC_RESPONSE_R1, &resp_data[0]);
                if (ret != 0) {
-                       return ret;
+                       retries--;
+                       continue;
                }
 
                if ((resp_data[0] & STATUS_SWITCH_ERROR) != 0U) {
@@ -129,7 +131,6 @@ static int mmc_sd_switch(unsigned int bus_width)
 {
        int ret;
        int retries = MMC_DEFAULT_MAX_RETRIES;
-       unsigned int scr[2] = { 0 };
        unsigned int bus_width_arg = 0;
 
        ret = ops->prepare(0, (uintptr_t)&scr, sizeof(scr));
@@ -341,8 +342,9 @@ static int sd_send_op_cond(void)
                }
 
                /* ACMD41: SD_SEND_OP_COND */
-               ret = mmc_send_cmd(MMC_ACMD(41), OCR_HCS, MMC_RESPONSE_R3,
-                                  &resp_data[0]);
+               ret = mmc_send_cmd(MMC_ACMD(41), OCR_HCS |
+                       mmc_dev_info->ocr_voltage, MMC_RESPONSE_R3,
+                       &resp_data[0]);
                if (ret != 0) {
                        return ret;
                }
index 2aaa28d6896bebb3d3e52132d1023c530acc9121..7611f019a1598ffb0a37ee1308d86c2627e5a8ae 100644 (file)
@@ -220,6 +220,7 @@ struct mmc_device_info {
        unsigned long long      device_size;    /* Size of device in bytes */
        unsigned int            block_size;     /* Block size in bytes */
        unsigned int            max_bus_freq;   /* Max bus freq in Hz */
+       unsigned int            ocr_voltage;    /* OCR voltage */
        enum mmc_device_type    mmc_dev_type;   /* Type of MMC */
 };