summaryrefslogtreecommitdiff
path: root/drivers/mmc
diff options
context:
space:
mode:
authorYann Gautier <yann.gautier@st.com>2018-08-02 13:46:17 +0200
committerYann Gautier <yann.gautier@st.com>2018-08-02 13:48:17 +0200
commit15e913d4ab2e67bef9583bc146f13642e0202091 (patch)
treef076b36c5b2e0eb74d93bd5ddd714b489ada4e63 /drivers/mmc
parentf214a8069822051f738f3fe8bec85dad0f0ac71f (diff)
mmc: add required delays when retrying commands
A new function mmc_reset_to_idle is also created. Signed-off-by: Yann Gautier <yann.gautier@st.com>
Diffstat (limited to 'drivers/mmc')
-rw-r--r--drivers/mmc/mmc.c77
1 files changed, 42 insertions, 35 deletions
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 8fe3239e..0c9ec101 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -9,6 +9,7 @@
#include <arch_helpers.h>
#include <assert.h>
#include <debug.h>
+#include <delay_timer.h>
#include <errno.h>
#include <mmc.h>
#include <stdbool.h>
@@ -319,18 +320,12 @@ static int mmc_fill_device_info(void)
static int sd_send_op_cond(void)
{
- int retries = SEND_OP_COND_MAX_RETRIES;
+ int n;
unsigned int resp_data[4];
- do {
+ for (n = 0; n < SEND_OP_COND_MAX_RETRIES; n++) {
int ret;
- if (retries == 0) {
- ERROR("ACMD41 failed after %d retries\n",
- SEND_OP_COND_MAX_RETRIES);
- return -EIO;
- }
-
/* CMD55: Application Specific Command */
ret = mmc_send_cmd(MMC_CMD(55), 0, MMC_RESPONSE_R(1), NULL);
if (ret != 0) {
@@ -344,25 +339,31 @@ static int sd_send_op_cond(void)
return ret;
}
- retries--;
- } while ((resp_data[0] & OCR_POWERUP) == 0U);
+ if ((resp_data[0] & OCR_POWERUP) != 0U) {
+ mmc_ocr_value = resp_data[0];
- mmc_ocr_value = resp_data[0];
+ if ((mmc_ocr_value & OCR_HCS) != 0U) {
+ mmc_dev_info->mmc_dev_type = MMC_IS_SD_HC;
+ } else {
+ mmc_dev_info->mmc_dev_type = MMC_IS_SD;
+ }
- if ((mmc_ocr_value & OCR_HCS) != 0U) {
- mmc_dev_info->mmc_dev_type = MMC_IS_SD_HC;
- } else {
- mmc_dev_info->mmc_dev_type = MMC_IS_SD;
+ return 0;
+ }
+
+ mdelay(1);
}
- return 0;
+ ERROR("ACMD41 failed after %d retries\n", SEND_OP_COND_MAX_RETRIES);
+
+ return -EIO;
}
-static int mmc_send_op_cond(void)
+static int mmc_reset_to_idle(void)
{
int ret;
- int retries = SEND_OP_COND_MAX_RETRIES;
- unsigned int resp_data[4];
+
+ mdelay(1);
/* CMD0: reset to IDLE */
ret = mmc_send_cmd(MMC_CMD(0), 0, 0, NULL);
@@ -370,14 +371,19 @@ static int mmc_send_op_cond(void)
return ret;
}
- do {
- if (retries == 0) {
- ERROR("CMD1 failed after %d retries\n",
- SEND_OP_COND_MAX_RETRIES);
- return -EIO;
- }
+ mdelay(2);
- /* CMD1: get OCR register (SEND_OP_COND) */
+ return 0;
+}
+
+static int mmc_send_op_cond(void)
+{
+ int ret, n;
+ unsigned int resp_data[4];
+
+ mmc_reset_to_idle();
+
+ for (n = 0; n < SEND_OP_COND_MAX_RETRIES; n++) {
ret = mmc_send_cmd(MMC_CMD(1), OCR_SECTOR_MODE |
OCR_VDD_MIN_2V7 | OCR_VDD_MIN_1V7,
MMC_RESPONSE_R(3), &resp_data[0]);
@@ -385,12 +391,17 @@ static int mmc_send_op_cond(void)
return ret;
}
- retries--;
- } while ((resp_data[0] & OCR_POWERUP) == 0U);
+ if ((resp_data[0] & OCR_POWERUP) != 0U) {
+ mmc_ocr_value = resp_data[0];
+ return 0;
+ }
- mmc_ocr_value = resp_data[0];
+ mdelay(1);
+ }
- return 0;
+ ERROR("CMD1 failed after %d retries\n", SEND_OP_COND_MAX_RETRIES);
+
+ return -EIO;
}
static int mmc_enumerate(unsigned int clk, unsigned int bus_width)
@@ -400,11 +411,7 @@ static int mmc_enumerate(unsigned int clk, unsigned int bus_width)
ops->init();
- /* CMD0: reset to IDLE */
- ret = mmc_send_cmd(MMC_CMD(0), 0, 0, NULL);
- if (ret != 0) {
- return ret;
- }
+ mmc_reset_to_idle();
/* CMD8: Send Interface Condition Command */
ret = mmc_send_cmd(MMC_CMD(8), VHS_2_7_3_6_V | CMD8_CHECK_PATTERN,