void mmmc_trace_before_send(struct mmc *mmc, struct mmc_cmd *cmd)
{
printf("CMD_SEND:%d\n", cmd->cmdidx);
- printf("\t\tARG\t\t\t 0x%08X\n", cmd->cmdarg);
+ printf("\t\tARG\t\t\t 0x%08x\n", cmd->cmdarg);
}
void mmmc_trace_after_send(struct mmc *mmc, struct mmc_cmd *cmd, int ret)
printf("\t\tMMC_RSP_NONE\n");
break;
case MMC_RSP_R1:
- printf("\t\tMMC_RSP_R1,5,6,7 \t 0x%08X \n",
+ printf("\t\tMMC_RSP_R1,5,6,7 \t 0x%08x \n",
cmd->response[0]);
break;
case MMC_RSP_R1b:
- printf("\t\tMMC_RSP_R1b\t\t 0x%08X \n",
+ printf("\t\tMMC_RSP_R1b\t\t 0x%08x \n",
cmd->response[0]);
break;
case MMC_RSP_R2:
- printf("\t\tMMC_RSP_R2\t\t 0x%08X \n",
+ printf("\t\tMMC_RSP_R2\t\t 0x%08x \n",
cmd->response[0]);
- printf("\t\t \t\t 0x%08X \n",
+ printf("\t\t \t\t 0x%08x \n",
cmd->response[1]);
- printf("\t\t \t\t 0x%08X \n",
+ printf("\t\t \t\t 0x%08x \n",
cmd->response[2]);
- printf("\t\t \t\t 0x%08X \n",
+ printf("\t\t \t\t 0x%08x \n",
cmd->response[3]);
printf("\n");
printf("\t\t\t\t\tDUMPING DATA\n");
ptr = (u8 *)&cmd->response[i];
ptr += 3;
for (j = 0; j < 4; j++)
- printf("%02X ", *ptr--);
+ printf("%02x ", *ptr--);
printf("\n");
}
break;
case MMC_RSP_R3:
- printf("\t\tMMC_RSP_R3,4\t\t 0x%08X \n",
+ printf("\t\tMMC_RSP_R3,4\t\t 0x%08x \n",
cmd->response[0]);
break;
default:
if (cmd.response[0] & MMC_STATUS_MASK) {
#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
- pr_err("Status Error: 0x%08X\n",
+ pr_err("Status Error: 0x%08x\n",
cmd.response[0]);
#endif
return -ECOMM;
return err;
}
-int mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value)
+static int __mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value,
+ bool send_status)
{
struct mmc_cmd cmd;
int timeout = 1000;
while (retries > 0) {
ret = mmc_send_cmd(mmc, &cmd, NULL);
- /* Waiting for the ready status */
- if (!ret) {
- ret = mmc_send_status(mmc, timeout);
- return ret;
+ if (ret) {
+ retries--;
+ continue;
+ }
+
+ if (!send_status) {
+ mdelay(50);
+ return 0;
}
- retries--;
+ /* Waiting for the ready status */
+ return mmc_send_status(mmc, timeout);
}
return ret;
}
+int mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value)
+{
+ return __mmc_switch(mmc, set, index, value, true);
+}
+
#if !CONFIG_IS_ENABLED(MMC_TINY)
static int mmc_set_card_speed(struct mmc *mmc, enum bus_mode mode,
bool hsdowngrade)
default:
return -EINVAL;
}
- err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_HS_TIMING,
- speed_bits);
+
+ err = __mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_HS_TIMING,
+ speed_bits, !hsdowngrade);
if (err)
return err;
return err;
}
+#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT) || \
+ CONFIG_IS_ENABLED(MMC_HS200_SUPPORT) || \
+ CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
+int mmc_deinit(struct mmc *mmc)
+{
+ u32 caps_filtered;
+
+ if (!mmc->has_init)
+ return 0;
+
+ if (IS_SD(mmc)) {
+ caps_filtered = mmc->card_caps &
+ ~(MMC_CAP(UHS_SDR12) | MMC_CAP(UHS_SDR25) |
+ MMC_CAP(UHS_SDR50) | MMC_CAP(UHS_DDR50) |
+ MMC_CAP(UHS_SDR104));
+
+ return sd_select_mode_and_width(mmc, caps_filtered);
+ } else {
+ caps_filtered = mmc->card_caps &
+ ~(MMC_CAP(MMC_HS_200) | MMC_CAP(MMC_HS_400));
+
+ return mmc_select_mode_and_width(mmc, caps_filtered);
+ }
+}
+#endif
+
int mmc_set_dsr(struct mmc *mmc, u16 val)
{
mmc->dsr = val;