From 04dd17822334871b23ea2862f7798fb0e0007777 Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Sat, 11 May 2024 08:53:19 +0000
Subject: [PATCH] change otg to host mode
---
u-boot/drivers/mmc/mmc.c | 77 ++++++++++++++++++++++++++++++++++++--
1 files changed, 72 insertions(+), 5 deletions(-)
diff --git a/u-boot/drivers/mmc/mmc.c b/u-boot/drivers/mmc/mmc.c
index 679fda6..590e4ba 100644
--- a/u-boot/drivers/mmc/mmc.c
+++ b/u-boot/drivers/mmc/mmc.c
@@ -1007,12 +1007,22 @@
return ret;
}
+static int mmc_switch_to_hs400(struct mmc *mmc)
+{
+ u8 val, fixed_drv_type, card_drv_type, drive_strength;
+
+ fixed_drv_type = mmc->cfg->fixed_drv_type;
+ card_drv_type = mmc->raw_driver_strength | mmc_driver_type_mask(0);
+ drive_strength = (card_drv_type & mmc_driver_type_mask(fixed_drv_type))
+ ? fixed_drv_type : 0;
+ val = EXT_CSD_TIMING_HS400 | drive_strength << EXT_CSD_DRV_STR_SHIFT;
+
+ return __mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_HS_TIMING, val, false);
+}
+
static int mmc_select_hs400(struct mmc *mmc)
{
int ret;
-
- /* Reduce frequency to HS frequency */
- mmc_set_clock(mmc, MMC_HIGH_52_MAX_DTR);
/* Switch card to HS mode */
ret = __mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
@@ -1022,6 +1032,9 @@
/* Set host controller to HS timing */
mmc_set_timing(mmc, MMC_TIMING_MMC_HS);
+
+ /* Reduce frequency to HS frequency */
+ mmc_set_clock(mmc, MMC_HIGH_52_MAX_DTR);
ret = mmc_send_status(mmc, 1000);
if (ret)
@@ -1035,8 +1048,7 @@
return ret;
/* Switch card to HS400 */
- ret = __mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
- EXT_CSD_HS_TIMING, EXT_CSD_TIMING_HS400, false);
+ ret = mmc_switch_to_hs400(mmc);
if (ret)
return ret;
@@ -1045,9 +1057,48 @@
return ret;
}
+
+static int mmc_select_hs400es(struct mmc *mmc)
+{
+ int err;
+
+ /* Switch card to HS mode */
+ err = __mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
+ EXT_CSD_HS_TIMING, EXT_CSD_TIMING_HS, false);
+ if (err)
+ return err;
+
+ /* Set host controller to HS timing */
+ mmc_set_timing(mmc, MMC_TIMING_MMC_HS);
+
+ err = mmc_send_status(mmc, 1000);
+ if (err)
+ return err;
+
+ mmc_set_clock(mmc, MMC_HIGH_52_MAX_DTR);
+
+ err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BUS_WIDTH,
+ EXT_CSD_DDR_BUS_WIDTH_8 |
+ EXT_CSD_BUS_WIDTH_STROBE);
+ if (err) {
+ printf("switch to bus width for hs400 failed\n");
+ return err;
+ }
+
+ /* Switch card to HS400 */
+ err = mmc_switch_to_hs400(mmc);
+ if (err)
+ return err;
+
+ /* Set host controller to HS400 timing and frequency */
+ mmc_set_timing(mmc, MMC_TIMING_MMC_HS400ES);
+
+ return mmc_set_enhanced_strobe(mmc);
+}
#else
static int mmc_select_hs200(struct mmc *mmc) { return 0; }
static int mmc_select_hs400(struct mmc *mmc) { return 0; }
+static int mmc_select_hs400es(struct mmc *mmc) { return 0; }
#endif
static u32 mmc_select_card_type(struct mmc *mmc, u8 *ext_csd)
@@ -1139,6 +1190,16 @@
return err;
avail_type = mmc_select_card_type(mmc, ext_csd);
+
+ if (avail_type & EXT_CSD_CARD_TYPE_HS400ES) {
+ err = mmc_select_bus_width(mmc);
+ if (err > 0 && mmc->bus_width == MMC_BUS_WIDTH_8BIT) {
+ err = mmc_select_hs400es(mmc);
+ mmc_set_bus_speed(mmc, avail_type);
+ if (!err)
+ return err;
+ }
+ }
if (avail_type & EXT_CSD_CARD_TYPE_HS200)
err = mmc_select_hs200(mmc);
@@ -1824,6 +1885,10 @@
mmc->erase_grp_size = 1;
mmc->part_config = MMCPART_NOAVAILABLE;
if (!IS_SD(mmc) && (mmc->version >= MMC_VERSION_4)) {
+ /* select high speed to reduce initialization time */
+ mmc_select_hs(mmc);
+ mmc_set_clock(mmc, MMC_HIGH_52_MAX_DTR);
+
/* check ext_csd version and capacity */
err = mmc_send_ext_csd(mmc, ext_csd);
if (err)
@@ -1973,6 +2038,8 @@
* ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
mmc->wr_rel_set = ext_csd[EXT_CSD_WR_REL_SET];
+
+ mmc->raw_driver_strength = ext_csd[EXT_CSD_DRIVER_STRENGTH];
}
err = mmc_set_capacity(mmc, mmc_get_blk_desc(mmc)->hwpart);
--
Gitblit v1.6.2