All of lore.kernel.org
 help / color / mirror / Atom feed
From: Ziyuan Xu <xzy.xu@rock-chips.com>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH 10/33] mmc: add support for HS200 mode of eMMC4.5
Date: Mon, 15 May 2017 14:07:04 +0800	[thread overview]
Message-ID: <1494828447-24332-10-git-send-email-xzy.xu@rock-chips.com> (raw)
In-Reply-To: <1494828447-24332-1-git-send-email-xzy.xu@rock-chips.com>

Add the support of the HS200 mode for eMMC 4.5 devices. The eMMC 4.5
device has support up to 200MHz bus speed, it can speed up the boot speed.

We can enable this feature via MMC_MODE_HS200 if the host controller has
the ability to support HS200 timing. Also the tuning feature required
when the HS200 mode is selected.

By the way, mmc card can only switch to high speed mode in SPL stage.

Signed-off-by: Ziyuan Xu <xzy.xu@rock-chips.com>
---

 drivers/mmc/mmc.c | 395 ++++++++++++++++++++++++++++++++++++------------------
 include/mmc.h     |  27 ++++
 2 files changed, 289 insertions(+), 133 deletions(-)

diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 9aee6ff..bebf8f3 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -318,6 +318,26 @@ ulong mmc_bread(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt,
 	return blkcnt;
 }
 
+void mmc_set_clock(struct mmc *mmc, uint clock)
+{
+	if (clock > mmc->cfg->f_max)
+		clock = mmc->cfg->f_max;
+
+	if (clock < mmc->cfg->f_min)
+		clock = mmc->cfg->f_min;
+
+	mmc->clock = clock;
+
+	mmc_set_ios(mmc);
+}
+
+static void mmc_set_bus_width(struct mmc *mmc, uint width)
+{
+	mmc->bus_width = width;
+
+	mmc_set_ios(mmc);
+}
+
 static void mmc_set_timing(struct mmc *mmc, uint timing)
 {
 	mmc->timing = timing;
@@ -587,6 +607,181 @@ int mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value)
 	return __mmc_switch(mmc, set, index, value, true);
 }
 
+static int mmc_select_bus_width(struct mmc *mmc)
+{
+	u32 ext_csd_bits[] = {
+		EXT_CSD_BUS_WIDTH_8,
+		EXT_CSD_BUS_WIDTH_4,
+	};
+	u32 bus_widths[] = {
+		MMC_BUS_WIDTH_8BIT,
+		MMC_BUS_WIDTH_4BIT,
+	};
+	ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
+	ALLOC_CACHE_ALIGN_BUFFER(u8, test_csd, MMC_MAX_BLOCK_LEN);
+	u32 idx, bus_width = 0;
+	int err = 0;
+
+	if (mmc->version < MMC_VERSION_4 ||
+	    !(mmc->cfg->host_caps & (MMC_MODE_4BIT | MMC_MODE_8BIT)))
+		return 0;
+
+	err = mmc_send_ext_csd(mmc, ext_csd);
+
+	if (err)
+		return err;
+
+	idx = (mmc->cfg->host_caps & MMC_MODE_8BIT) ? 0 : 1;
+
+	/*
+	 * Unlike SD, MMC cards dont have a configuration register to notify
+	 * supported bus width. So bus test command should be run to identify
+	 * the supported bus width or compare the ext csd values of current
+	 * bus width and ext csd values of 1 bit mode read earlier.
+	 */
+	for (; idx < ARRAY_SIZE(bus_widths); idx++) {
+		/*
+		 * Host is capable of 8bit transfer, then switch
+		 * the device to work in 8bit transfer mode. If the
+		 * mmc switch command returns error then switch to
+		 * 4bit transfer mode. On success set the corresponding
+		 * bus width on the host.
+		 */
+		err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
+				 EXT_CSD_BUS_WIDTH, ext_csd_bits[idx]);
+		if (err)
+			continue;
+
+		bus_width = bus_widths[idx];
+		mmc_set_bus_width(mmc, bus_width);
+
+		err = mmc_send_ext_csd(mmc, test_csd);
+
+		if (err)
+			continue;
+
+		/* Only compare read only fields */
+		if ((ext_csd[EXT_CSD_PARTITIONING_SUPPORT] ==
+			test_csd[EXT_CSD_PARTITIONING_SUPPORT]) &&
+		    (ext_csd[EXT_CSD_HC_WP_GRP_SIZE] ==
+			test_csd[EXT_CSD_HC_WP_GRP_SIZE]) &&
+		    (ext_csd[EXT_CSD_REV] == test_csd[EXT_CSD_REV]) &&
+			(ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] ==
+			test_csd[EXT_CSD_HC_ERASE_GRP_SIZE]) &&
+		    !memcmp(&ext_csd[EXT_CSD_SEC_CNT],
+			&test_csd[EXT_CSD_SEC_CNT], 4)) {
+			err = bus_width;
+			break;
+		} else {
+			err = -EBADMSG;
+		}
+	}
+
+	return err;
+}
+
+static const u8 tuning_blk_pattern_4bit[] = {
+	0xff, 0x0f, 0xff, 0x00, 0xff, 0xcc, 0xc3, 0xcc,
+	0xc3, 0x3c, 0xcc, 0xff, 0xfe, 0xff, 0xfe, 0xef,
+	0xff, 0xdf, 0xff, 0xdd, 0xff, 0xfb, 0xff, 0xfb,
+	0xbf, 0xff, 0x7f, 0xff, 0x77, 0xf7, 0xbd, 0xef,
+	0xff, 0xf0, 0xff, 0xf0, 0x0f, 0xfc, 0xcc, 0x3c,
+	0xcc, 0x33, 0xcc, 0xcf, 0xff, 0xef, 0xff, 0xee,
+	0xff, 0xfd, 0xff, 0xfd, 0xdf, 0xff, 0xbf, 0xff,
+	0xbb, 0xff, 0xf7, 0xff, 0xf7, 0x7f, 0x7b, 0xde,
+};
+
+static const u8 tuning_blk_pattern_8bit[] = {
+	0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00,
+	0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc, 0xcc,
+	0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff, 0xff,
+	0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee, 0xff,
+	0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd, 0xdd,
+	0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff, 0xbb,
+	0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff, 0xff,
+	0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee, 0xff,
+	0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00,
+	0x00, 0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc,
+	0xcc, 0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff,
+	0xff, 0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee,
+	0xff, 0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd,
+	0xdd, 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff,
+	0xbb, 0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff,
+	0xff, 0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee,
+};
+
+int mmc_send_tuning(struct mmc *mmc, u32 opcode)
+{
+	struct mmc_cmd cmd;
+	struct mmc_data data;
+	const u8 *tuning_block_pattern;
+	int size, err = 0;
+	u8 *data_buf;
+
+	if (mmc->bus_width == MMC_BUS_WIDTH_8BIT) {
+		tuning_block_pattern = tuning_blk_pattern_8bit;
+		size = sizeof(tuning_blk_pattern_8bit);
+	} else if (mmc->bus_width == MMC_BUS_WIDTH_4BIT) {
+		tuning_block_pattern = tuning_blk_pattern_4bit;
+		size = sizeof(tuning_blk_pattern_4bit);
+	} else {
+		return -EINVAL;
+	}
+
+	data_buf = calloc(1, size);
+	if (!data_buf)
+		return -ENOMEM;
+
+	cmd.cmdidx = opcode;
+	cmd.resp_type = MMC_RSP_R1;
+	cmd.cmdarg = 0;
+
+	data.dest = (char *)data_buf;
+	data.blocksize = size;
+	data.blocks = 1;
+	data.flags = MMC_DATA_READ;
+
+	err = mmc_send_cmd(mmc, &cmd, &data);
+	if (err)
+		goto out;
+
+	if (memcmp(data_buf, tuning_block_pattern, size))
+		err = -EIO;
+out:
+	free(data_buf);
+	return err;
+}
+
+static int mmc_execute_tuning(struct mmc *mmc)
+{
+#ifdef CONFIG_DM_MMC_OPS
+	struct dm_mmc_ops *ops = mmc_get_ops(mmc->dev);
+#endif
+	u32 opcode;
+
+	if (IS_SD(mmc))
+		opcode = MMC_SEND_TUNING_BLOCK;
+	else
+		opcode = MMC_SEND_TUNING_BLOCK_HS200;
+
+#ifndef CONFIG_DM_MMC_OPS
+	if (mmc->cfg->ops->execute_tuning) {
+		return mmc->cfg->ops->execute_tuning(mmc, opcode);
+#else
+	if (ops->execute_tuning) {
+		return ops->execute_tuning(mmc->dev, opcode);
+#endif
+	} else {
+		debug("Tuning feature required for HS200 mode.\n");
+		return -EIO;
+	}
+}
+
+static int mmc_hs200_tuning(struct mmc *mmc)
+{
+	return mmc_execute_tuning(mmc);
+}
+
 static int mmc_select_hs(struct mmc *mmc)
 {
 	int ret;
@@ -600,6 +795,45 @@ static int mmc_select_hs(struct mmc *mmc)
 	return ret;
 }
 
+#ifndef CONFIG_SPL_BUILD
+static int mmc_select_hs200(struct mmc *mmc)
+{
+	int ret;
+	struct mmc_cmd cmd;
+
+	/*
+	 * Set the bus width(4 or 8) with host's support and
+	 * switch to HS200 mode if bus width is set successfully.
+	 */
+	ret = mmc_select_bus_width(mmc);
+
+	if (ret > 0) {
+		ret = __mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
+				   EXT_CSD_HS_TIMING,
+				   EXT_CSD_TIMING_HS200, false);
+
+		if (ret)
+			return ret;
+
+		mmc_set_timing(mmc, MMC_TIMING_MMC_HS200);
+
+		cmd.cmdidx = MMC_CMD_SEND_STATUS;
+		cmd.resp_type = MMC_RSP_R1;
+		cmd.cmdarg = mmc->rca << 16;
+
+		ret = mmc_send_cmd(mmc, &cmd, NULL);
+
+		if (ret)
+			return ret;
+
+		if (cmd.response[0] & MMC_STATUS_SWITCH_ERROR)
+			return -EBADMSG;
+	}
+
+	return ret;
+}
+#endif
+
 static u32 mmc_select_card_type(struct mmc *mmc, u8 *ext_csd)
 {
 	u8 card_type;
@@ -651,10 +885,24 @@ static u32 mmc_select_card_type(struct mmc *mmc, u8 *ext_csd)
 	return avail_type;
 }
 
+static void mmc_set_bus_speed(struct mmc *mmc, u8 avail_type)
+{
+	int clock = 0;
+
+	if (mmc_card_hs(mmc))
+		clock = (avail_type & EXT_CSD_CARD_TYPE_52) ?
+			MMC_HIGH_52_MAX_DTR : MMC_HIGH_26_MAX_DTR;
+	else if (mmc_card_hs200(mmc) ||
+		 mmc_card_hs400(mmc) ||
+		 mmc_card_hs400es(mmc))
+		clock = MMC_HS200_MAX_DTR;
+
+	mmc_set_clock(mmc, clock);
+}
+
 static int mmc_change_freq(struct mmc *mmc)
 {
 	ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
-	char cardtype;
 	u32 avail_type;
 	int err;
 
@@ -674,9 +922,13 @@ static int mmc_change_freq(struct mmc *mmc)
 	if (err)
 		return err;
 
-	cardtype = ext_csd[EXT_CSD_CARD_TYPE] & 0xf;
 	avail_type = mmc_select_card_type(mmc, ext_csd);
 
+#ifndef CONFIG_SPL_BUILD
+	if (avail_type & EXT_CSD_CARD_TYPE_HS200)
+		err = mmc_select_hs200(mmc);
+	else
+#endif
 	if (avail_type & EXT_CSD_CARD_TYPE_HS)
 		err = mmc_select_hs(mmc);
 	else
@@ -685,26 +937,14 @@ static int mmc_change_freq(struct mmc *mmc)
 	if (err)
 		return err;
 
-	/* Now check to see that it worked */
-	err = mmc_send_ext_csd(mmc, ext_csd);
-
-	if (err)
-		return err;
+	mmc_set_bus_speed(mmc, avail_type);
 
-	/* No high-speed support */
-	if (!ext_csd[EXT_CSD_HS_TIMING])
-		return 0;
-
-	/* High Speed is set, there are two types: 52MHz and 26MHz */
-	if (cardtype & EXT_CSD_CARD_TYPE_52) {
-		if (cardtype & EXT_CSD_CARD_TYPE_DDR_1_8V)
-			mmc->card_caps |= MMC_MODE_DDR_52MHz;
-		mmc->card_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS;
-	} else {
-		mmc->card_caps |= MMC_MODE_HS;
-	}
+	if (mmc_card_hs200(mmc))
+		err = mmc_hs200_tuning(mmc);
+	else
+		err = mmc_select_bus_width(mmc) > 0 ? 0 : err;
 
-	return 0;
+	return err;
 }
 
 static int mmc_set_capacity(struct mmc *mmc, int part_num)
@@ -1206,26 +1446,6 @@ static bool mmc_can_card_busy(struct mmc *)
 }
 #endif
 
-void mmc_set_clock(struct mmc *mmc, uint clock)
-{
-	if (clock > mmc->cfg->f_max)
-		clock = mmc->cfg->f_max;
-
-	if (clock < mmc->cfg->f_min)
-		clock = mmc->cfg->f_min;
-
-	mmc->clock = clock;
-
-	mmc_set_ios(mmc);
-}
-
-static void mmc_set_bus_width(struct mmc *mmc, uint width)
-{
-	mmc->bus_width = width;
-
-	mmc_set_ios(mmc);
-}
-
 static int mmc_startup(struct mmc *mmc)
 {
 	int err, i;
@@ -1233,7 +1453,6 @@ static int mmc_startup(struct mmc *mmc)
 	u64 cmult, csize, capacity;
 	struct mmc_cmd cmd;
 	ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
-	ALLOC_CACHE_ALIGN_BUFFER(u8, test_csd, MMC_MAX_BLOCK_LEN);
 	bool has_parts = false;
 	bool part_completed;
 	struct blk_desc *bdesc;
@@ -1576,102 +1795,12 @@ static int mmc_startup(struct mmc *mmc)
 			mmc->tran_speed = 50000000;
 		else
 			mmc->tran_speed = 25000000;
-	} else if (mmc->version >= MMC_VERSION_4) {
-		/* Only version 4 of MMC supports wider bus widths */
-		int idx;
-
-		/* An array of possible bus widths in order of preference */
-		static unsigned ext_csd_bits[] = {
-			EXT_CSD_DDR_BUS_WIDTH_8,
-			EXT_CSD_DDR_BUS_WIDTH_4,
-			EXT_CSD_BUS_WIDTH_8,
-			EXT_CSD_BUS_WIDTH_4,
-			EXT_CSD_BUS_WIDTH_1,
-		};
-
-		/* An array to map CSD bus widths to host cap bits */
-		static unsigned ext_to_hostcaps[] = {
-			[EXT_CSD_DDR_BUS_WIDTH_4] =
-				MMC_MODE_DDR_52MHz | MMC_MODE_4BIT,
-			[EXT_CSD_DDR_BUS_WIDTH_8] =
-				MMC_MODE_DDR_52MHz | MMC_MODE_8BIT,
-			[EXT_CSD_BUS_WIDTH_4] = MMC_MODE_4BIT,
-			[EXT_CSD_BUS_WIDTH_8] = MMC_MODE_8BIT,
-		};
-
-		/* An array to map chosen bus width to an integer */
-		static unsigned widths[] = {
-			8, 4, 8, 4, 1,
-		};
-
-		for (idx=0; idx < ARRAY_SIZE(ext_csd_bits); idx++) {
-			unsigned int extw = ext_csd_bits[idx];
-			unsigned int caps = ext_to_hostcaps[extw];
-
-			/*
-			 * If the bus width is still not changed,
-			 * don't try to set the default again.
-			 * Otherwise, recover from switch attempts
-			 * by switching to 1-bit bus width.
-			 */
-			if (extw == EXT_CSD_BUS_WIDTH_1 &&
-					mmc->bus_width == 1) {
-				err = 0;
-				break;
-			}
-
-			/*
-			 * Check to make sure the card and controller support
-			 * these capabilities
-			 */
-			if ((mmc->card_caps & caps) != caps)
-				continue;
-
-			err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
-					EXT_CSD_BUS_WIDTH, extw);
-
-			if (err)
-				continue;
-
-			mmc->ddr_mode = (caps & MMC_MODE_DDR_52MHz) ? 1 : 0;
-			mmc_set_bus_width(mmc, widths[idx]);
 
-			err = mmc_send_ext_csd(mmc, test_csd);
-
-			if (err)
-				continue;
-
-			/* Only compare read only fields */
-			if (ext_csd[EXT_CSD_PARTITIONING_SUPPORT]
-				== test_csd[EXT_CSD_PARTITIONING_SUPPORT] &&
-			    ext_csd[EXT_CSD_HC_WP_GRP_SIZE]
-				== test_csd[EXT_CSD_HC_WP_GRP_SIZE] &&
-			    ext_csd[EXT_CSD_REV]
-				== test_csd[EXT_CSD_REV] &&
-			    ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]
-				== test_csd[EXT_CSD_HC_ERASE_GRP_SIZE] &&
-			    memcmp(&ext_csd[EXT_CSD_SEC_CNT],
-				   &test_csd[EXT_CSD_SEC_CNT], 4) == 0)
-				break;
-			else
-				err = -EBADMSG;
-		}
-
-		if (err)
-			return err;
-
-		if (mmc->card_caps & MMC_MODE_HS) {
-			if (mmc->card_caps & MMC_MODE_HS_52MHz)
-				mmc->tran_speed = 52000000;
-			else
-				mmc->tran_speed = 26000000;
-		}
+		mmc_set_clock(mmc, mmc->tran_speed);
 	}
 
-	mmc_set_clock(mmc, mmc->tran_speed);
-
 	/* Fix the block length for DDR mode */
-	if (mmc->ddr_mode) {
+	if (mmc_card_ddr(mmc)) {
 		mmc->read_bl_len = MMC_MAX_BLOCK_LEN;
 		mmc->write_bl_len = MMC_MAX_BLOCK_LEN;
 	}
diff --git a/include/mmc.h b/include/mmc.h
index 9bed935..a2ef986 100644
--- a/include/mmc.h
+++ b/include/mmc.h
@@ -85,6 +85,8 @@
 #define MMC_CMD_SET_BLOCKLEN		16
 #define MMC_CMD_READ_SINGLE_BLOCK	17
 #define MMC_CMD_READ_MULTIPLE_BLOCK	18
+#define MMC_SEND_TUNING_BLOCK		19
+#define MMC_SEND_TUNING_BLOCK_HS200	21
 #define MMC_CMD_SET_BLOCK_COUNT         23
 #define MMC_CMD_WRITE_SINGLE_BLOCK	24
 #define MMC_CMD_WRITE_MULTIPLE_BLOCK	25
@@ -387,6 +389,17 @@ struct dm_mmc_ops {
 	 * @return 0 if write-enabled, 1 if write-protected, -ve on error
 	 */
 	int (*get_wp)(struct udevice *dev);
+
+	/**
+	 * execute_tuning() - Find the optimal sampling point of a data
+	 *			input signals.
+	 *
+	 * @dev:	Device to check
+	 * @opcode:	The tuning command opcode value is different
+	 *		for SD and eMMC cards
+	 * @return 0 if write-enabled, 1 if write-protected, -ve on error
+	 */
+	int (*execute_tuning)(struct udevice *dev, u32 opcode);
 };
 
 #define mmc_get_ops(dev)        ((struct dm_mmc_ops *)(dev)->driver->ops)
@@ -413,6 +426,7 @@ struct mmc_ops {
 	int (*init)(struct mmc *mmc);
 	int (*getcd)(struct mmc *mmc);
 	int (*getwp)(struct mmc *mmc);
+	int (*execute_tuning)(struct udevice *dev, u32 opcode);
 };
 #endif
 
@@ -451,6 +465,11 @@ struct mmc {
 	uint has_init;
 	int high_capacity;
 	uint bus_width;
+
+#define MMC_BUS_WIDTH_1BIT	1
+#define MMC_BUS_WIDTH_4BIT	4
+#define MMC_BUS_WIDTH_8BIT	8
+
 	uint timing;
 
 #define MMC_TIMING_LEGACY	0
@@ -467,6 +486,12 @@ struct mmc {
 #define MMC_TIMING_MMC_HS400ES	11
 
 	uint clock;
+
+#define MMC_HIGH_26_MAX_DTR	26000000
+#define MMC_HIGH_52_MAX_DTR	52000000
+#define MMC_HIGH_DDR_MAX_DTR	52000000
+#define MMC_HS200_MAX_DTR	200000000
+
 	uint card_caps;
 	uint ocr;
 	uint dsr;
@@ -559,6 +584,8 @@ static inline bool mmc_card_hs400es(struct mmc *mmc)
 	return mmc->timing == MMC_TIMING_MMC_HS400ES;
 }
 
+int mmc_send_tuning(struct mmc *mmc, u32 opcode);
+
 struct mmc *mmc_create(const struct mmc_config *cfg, void *priv);
 
 /**
-- 
2.7.4

  parent reply	other threads:[~2017-05-15  6:07 UTC|newest]

Thread overview: 44+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-05-15  6:06 [U-Boot] [PATCH 01/33] mmc: select the available type from host_caps and card_caps Ziyuan Xu
2017-05-15  6:06 ` [U-Boot] [PATCH 02/33] mmc: add set_timing entry for timing selection Ziyuan Xu
2017-05-15  6:06 ` [U-Boot] [PATCH 03/33] mmc: xenon_sdhci: drop redundant timing definitions Ziyuan Xu
2017-05-15  6:06 ` [U-Boot] [PATCH 04/33] mmc: rework high speed mode selection Ziyuan Xu
2017-05-15  6:06 ` [U-Boot] [PATCH 05/33] mmc: sdhci: fix HISPD bit setting Ziyuan Xu
2017-05-15  6:07 ` [U-Boot] [PATCH 06/33] mmc: add card_busy to query card status Ziyuan Xu
2017-05-25 13:02   ` Jaehoon Chung
2017-05-15  6:07 ` [U-Boot] [PATCH 07/33] mmc: dw_mmc: implement card_busy detection Ziyuan Xu
2017-05-15  6:07 ` [U-Boot] [PATCH 08/33] mmc: sdhci: " Ziyuan Xu
2017-05-15  6:07 ` [U-Boot] [PATCH 09/33] mmc: rework mmc_switch for non-send_status scenario Ziyuan Xu
2017-05-15  6:07 ` Ziyuan Xu [this message]
2017-05-15  6:07 ` [U-Boot] [PATCH 11/33] mmc: rework ddr mode judgement with timing Ziyuan Xu
2017-05-15  6:07 ` [U-Boot] [PATCH 12/33] mmc: remove tran_speed from struct mmc Ziyuan Xu
2017-05-15  6:07 ` [U-Boot] [PATCH 13/33] cmd: mmc: show the current speed mode Ziyuan Xu
2017-05-15  6:07 ` [U-Boot] [PATCH 14/33] clk: introduce clk_phase get/set function & callback Ziyuan Xu
2017-05-15  6:07 ` [U-Boot] [PATCH 15/33] rockchip: clk: rk3288: fix mmc clock setting Ziyuan Xu
2017-05-15  6:07 ` [U-Boot] [PATCH 16/33] rockchip: clk: rk3288: add support for the clock phase Ziyuan Xu
2017-05-15  6:07 ` [U-Boot] [PATCH 17/33] rockchip: clk: rk3399: fix emmc clock setting Ziyuan Xu
2017-05-15  6:07 ` [U-Boot] [PATCH 18/33] mmc: dw_mmc: add the support for the tuning scheme Ziyuan Xu
2017-05-15  6:07 ` [U-Boot] [PATCH 19/33] mmc: dw_mmc: rockchip: implement tuning with clock phase framework Ziyuan Xu
2017-05-15  6:07 ` [U-Boot] [PATCH 20/33] mmc: dw_mmc: reset controller after data error Ziyuan Xu
2017-05-15  6:07 ` [U-Boot] [PATCH 21/33] mmc: add DDR52 support for eMMC card Ziyuan Xu
2017-05-15  6:07 ` [U-Boot] [PATCH 22/33] mmc: dw_mmc: rockchip: fix data crc error on ddr52 8bit mode Ziyuan Xu
2017-05-15  6:07 ` [U-Boot] [PATCH 23/33] mmc: dw_mmc: fix bus width setting Ziyuan Xu
2017-05-15  6:07 ` [U-Boot] [PATCH 24/33] mmc: sdhci: rockchip: " Ziyuan Xu
2017-05-15  6:07 ` [U-Boot] [PATCH 25/33] mmc: sdhci: update host->clock after clock setting Ziyuan Xu
2017-05-15  6:07 ` [U-Boot] [PATCH 26/33] mmc: sdhci: add support for UHS timing Ziyuan Xu
2017-05-15  6:07 ` [U-Boot] [PATCH 27/33] mmc: sdhci: rename set_clock callback Ziyuan Xu
2017-05-15  6:07 ` [U-Boot] [PATCH 28/33] mmc: sdhci: export sdhci_set_clock() Ziyuan Xu
2017-05-15  6:07 ` [U-Boot] [PATCH 29/33] mmc: sdhci: rockchip: add phy support Ziyuan Xu
2017-05-15  6:07 ` [U-Boot] [PATCH 30/33] mmc: sdhci: add the support for tuning Ziyuan Xu
2017-05-15  6:07 ` [U-Boot] [PATCH 31/33] mmc: add support for HS400 mode of eMMC5.0 Ziyuan Xu
2017-05-15  6:07 ` [U-Boot] [PATCH 32/33] dts: rk3399: change the maximum eMMC clock frequency to 150MHz Ziyuan Xu
2017-05-15  6:07 ` [U-Boot] [PATCH 33/33] SPL: tiny-printf: add "X" modifier Ziyuan Xu
2017-05-16  0:18 ` [U-Boot] [PATCH 01/33] mmc: select the available type from host_caps and card_caps Simon Glass
2017-05-16  1:15   ` Ziyuan
2017-05-16  1:55     ` Jaehoon Chung
2017-05-16  2:22       ` Ziyuan
2017-05-25  8:12       ` Ziyuan
2017-05-25 10:50         ` Jaehoon Chung
2017-05-25 13:08         ` Jaehoon Chung
2017-06-05  0:50           ` Ziyuan
2017-06-05  1:13             ` Jaehoon Chung
2017-05-17  1:38     ` Simon Glass

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1494828447-24332-10-git-send-email-xzy.xu@rock-chips.com \
    --to=xzy.xu@rock-chips.com \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.