From 9df731a176aab8e03b984b681b1bea01ccff6644 Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Mon, 06 Nov 2023 07:23:06 +0000
Subject: [PATCH] rk3568 rt uboot init

---
 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