From 4362b29e7f03a2598800e3856058b10ec80e5788 Mon Sep 17 00:00:00 2001 From: Yann Gautier <yann.gautier@st.com> Date: Wed, 12 Jun 2019 15:48:05 +0200 Subject: [PATCH] mmc: stm32_sdmmc2: manage CMD6 For SD-cards, CMD6 is used to switch functions, like setting high speed mode. As it has another meaning for eMMC, and may not work on standard capacity SD-cards, it must be checked with MMC_IS_SD_HC flag. As ACMD6 is also used, and will have the same index, a check on CMD/ACMD commands is done: a boolean is stored depending on previous command. It is set to true if CMD55 is issued, for other commands it is set to false. Change-Id: I6c2b9c7637656f858601ec075de1cb5f57af271a Signed-off-by: Yann Gautier <yann.gautier@st.com> Reviewed-on: https://gerrit.st.com/c/mpu/oe/st/tf-a/+/135782 Reviewed-by: CITOOLS <smet-aci-reviews@lists.codex.cro.st.com> Reviewed-by: CIBUILD <smet-aci-builds@lists.codex.cro.st.com> Reviewed-by: Lionel DEBIEVE <lionel.debieve@st.com> --- drivers/st/mmc/stm32_sdmmc2.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/drivers/st/mmc/stm32_sdmmc2.c b/drivers/st/mmc/stm32_sdmmc2.c index cff3a344f..9a8bd7981 100644 --- a/drivers/st/mmc/stm32_sdmmc2.c +++ b/drivers/st/mmc/stm32_sdmmc2.c @@ -138,6 +138,8 @@ static const struct mmc_ops stm32_sdmmc2_ops = { static struct stm32_sdmmc2_params sdmmc2_params; +static bool next_cmd_is_acmd; + #pragma weak plat_sdmmc2_use_dma bool plat_sdmmc2_use_dma(unsigned int instance, unsigned int memory) { @@ -221,6 +223,20 @@ static int stm32_sdmmc2_send_cmd_req(struct mmc_cmd *cmd) case MMC_CMD(1): arg_reg |= OCR_POWERUP; break; + case MMC_CMD(6): + if ((sdmmc2_params.device_info->mmc_dev_type == MMC_IS_SD_HC) && + (!next_cmd_is_acmd)) { + cmd_reg |= SDMMC_CMDR_CMDTRANS; + if (sdmmc2_params.use_dma) { + flags_data |= SDMMC_STAR_DCRCFAIL | + SDMMC_STAR_DTIMEOUT | + SDMMC_STAR_DATAEND | + SDMMC_STAR_RXOVERR | + SDMMC_STAR_IDMATE | + SDMMC_STAR_DBCKEND; + } + } + break; case MMC_CMD(8): if (sdmmc2_params.device_info->mmc_dev_type == MMC_IS_EMMC) { cmd_reg |= SDMMC_CMDR_CMDTRANS; @@ -258,6 +274,8 @@ static int stm32_sdmmc2_send_cmd_req(struct mmc_cmd *cmd) break; } + next_cmd_is_acmd = (cmd->cmd_idx == MMC_CMD(55)); + mmio_write_32(base + SDMMC_ICR, SDMMC_STATIC_FLAGS); /* @@ -265,8 +283,7 @@ static int stm32_sdmmc2_send_cmd_req(struct mmc_cmd *cmd) * Skip CMD55 as the next command could be data related, and * the register could have been set in prepare function. */ - if (((cmd_reg & SDMMC_CMDR_CMDTRANS) == 0U) && - (cmd->cmd_idx != MMC_CMD(55))) { + if (((cmd_reg & SDMMC_CMDR_CMDTRANS) == 0U) && !next_cmd_is_acmd) { mmio_write_32(base + SDMMC_DCTRLR, 0U); } -- GitLab