All of lore.kernel.org
 help / color / mirror / Atom feed
* [U-Boot] [PATCH 01/33] mmc: select the available type from host_caps and card_caps
@ 2017-05-15  5:56 Ziyuan Xu
  2017-05-15  5:56 ` [U-Boot] [PATCH 02/33] mmc: add set_timing entry for timing selection Ziyuan Xu
                   ` (3 more replies)
  0 siblings, 4 replies; 6+ messages in thread
From: Ziyuan Xu @ 2017-05-15  5:56 UTC (permalink / raw)
  To: u-boot

The original implementation select HS timing by default, add available
type selection for higher speed mode compatibility, such as hs200,
hs400, hs400es.

By the way, we assume that card run at 1.8V or 1.2V I/O when its timing
is ddr52/hs200/hs400(es).

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

 drivers/mmc/mmc.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 include/mmc.h     | 16 +++++++++++++++
 2 files changed, 74 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 72fc177..f5b2280 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -546,10 +546,62 @@ int mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value)
 
 }
 
+static u32 mmc_select_card_type(struct mmc *mmc, u8 *ext_csd)
+{
+	u8 card_type;
+	u32 host_caps, avail_type = 0;
+
+	card_type = ext_csd[EXT_CSD_CARD_TYPE];
+	host_caps = mmc->cfg->host_caps;
+
+	if ((host_caps & MMC_MODE_HS) &&
+	    (card_type & EXT_CSD_CARD_TYPE_26))
+		avail_type |= EXT_CSD_CARD_TYPE_26;
+
+	if ((host_caps & MMC_MODE_HS) &&
+	    (card_type & EXT_CSD_CARD_TYPE_52))
+		avail_type |= EXT_CSD_CARD_TYPE_52;
+
+	/*
+	 * For the moment, u-boot doesn't support signal voltage
+	 * switch, therefor we assume that host support ddr52
+	 * at 1.8v or 3.3v I/O(1.2v I/O not supported, hs200 and
+	 * hs400 are the same).
+	 */
+	if ((host_caps & MMC_MODE_DDR_52MHz) &&
+	    (card_type & EXT_CSD_CARD_TYPE_DDR_1_8V))
+		avail_type |= EXT_CSD_CARD_TYPE_DDR_1_8V;
+
+	if ((host_caps & MMC_MODE_HS200) &&
+	    (card_type & EXT_CSD_CARD_TYPE_HS200_1_8V))
+		avail_type |= EXT_CSD_CARD_TYPE_HS200_1_8V;
+
+	/*
+	 * If host can support HS400, it means that host can also
+	 * support HS200.
+	 */
+	if ((host_caps & MMC_MODE_HS400) &&
+	    (host_caps & MMC_MODE_8BIT) &&
+	    (card_type & EXT_CSD_CARD_TYPE_HS400_1_8V))
+		avail_type |= EXT_CSD_CARD_TYPE_HS200_1_8V |
+				EXT_CSD_CARD_TYPE_HS400_1_8V;
+
+	if ((host_caps & MMC_MODE_HS400ES) &&
+	    (host_caps & MMC_MODE_8BIT) &&
+	    ext_csd[EXT_CSD_STROBE_SUPPORT] &&
+	    (avail_type & EXT_CSD_CARD_TYPE_HS400_1_8V))
+		avail_type |= EXT_CSD_CARD_TYPE_HS200_1_8V |
+				EXT_CSD_CARD_TYPE_HS400_1_8V |
+				EXT_CSD_CARD_TYPE_HS400ES;
+
+	return avail_type;
+}
+
 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;
 
 	mmc->card_caps = 0;
@@ -569,8 +621,13 @@ static int mmc_change_freq(struct mmc *mmc)
 		return err;
 
 	cardtype = ext_csd[EXT_CSD_CARD_TYPE] & 0xf;
+	avail_type = mmc_select_card_type(mmc, ext_csd);
 
-	err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_HS_TIMING, 1);
+	if (avail_type & EXT_CSD_CARD_TYPE_HS)
+		err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
+				 EXT_CSD_HS_TIMING, 1);
+	else
+		err = -EINVAL;
 
 	if (err)
 		return err;
diff --git a/include/mmc.h b/include/mmc.h
index fad12d6..0bae1a1 100644
--- a/include/mmc.h
+++ b/include/mmc.h
@@ -58,6 +58,9 @@
 #define MMC_MODE_8BIT		(1 << 3)
 #define MMC_MODE_SPI		(1 << 4)
 #define MMC_MODE_DDR_52MHz	(1 << 5)
+#define MMC_MODE_HS200		(1 << 6)
+#define MMC_MODE_HS400		(1 << 7)
+#define MMC_MODE_HS400ES	(1 << 8)
 
 #define SD_DATA_4BIT	0x00040000
 
@@ -182,6 +185,7 @@
 #define EXT_CSD_BOOT_BUS_WIDTH		177
 #define EXT_CSD_PART_CONF		179	/* R/W */
 #define EXT_CSD_BUS_WIDTH		183	/* R/W */
+#define EXT_CSD_STROBE_SUPPORT		184	/* RO */
 #define EXT_CSD_HS_TIMING		185	/* R/W */
 #define EXT_CSD_REV			192	/* RO */
 #define EXT_CSD_CARD_TYPE		196	/* RO */
@@ -201,6 +205,18 @@
 
 #define EXT_CSD_CARD_TYPE_26	(1 << 0)	/* Card can run at 26MHz */
 #define EXT_CSD_CARD_TYPE_52	(1 << 1)	/* Card can run at 52MHz */
+#define EXT_CSD_CARD_TYPE_HS	(EXT_CSD_CARD_TYPE_26 | \
+				 EXT_CSD_CARD_TYPE_52)
+#define EXT_CSD_CARD_TYPE_HS200_1_8V	BIT(4)	/* Card can run at 200MHz */
+#define EXT_CSD_CARD_TYPE_HS200_1_2V	BIT(5)	/* Card can run at 200MHz */
+#define EXT_CSD_CARD_TYPE_HS200		(EXT_CSD_CARD_TYPE_HS200_1_8V | \
+					 EXT_CSD_CARD_TYPE_HS200_1_2V)
+#define EXT_CSD_CARD_TYPE_HS400_1_8V	BIT(6)	/* Card can run at 200MHz DDR, 1.8V */
+#define EXT_CSD_CARD_TYPE_HS400_1_2V	BIT(7)	/* Card can run at 200MHz DDR, 1.2V */
+#define EXT_CSD_CARD_TYPE_HS400		(EXT_CSD_CARD_TYPE_HS400_1_8V | \
+					 EXT_CSD_CARD_TYPE_HS400_1_2V)
+#define EXT_CSD_CARD_TYPE_HS400ES	BIT(8)	/* Card can run@HS400ES */
+
 #define EXT_CSD_CARD_TYPE_DDR_1_8V	(1 << 2)
 #define EXT_CSD_CARD_TYPE_DDR_1_2V	(1 << 3)
 #define EXT_CSD_CARD_TYPE_DDR_52	(EXT_CSD_CARD_TYPE_DDR_1_8V \
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 6+ messages in thread
* [U-Boot] [PATCH 01/33] mmc: select the available type from host_caps and card_caps
@ 2017-05-15  6:06 Ziyuan Xu
  2017-05-15  6:06 ` [U-Boot] [PATCH 02/33] mmc: add set_timing entry for timing selection Ziyuan Xu
  0 siblings, 1 reply; 6+ messages in thread
From: Ziyuan Xu @ 2017-05-15  6:06 UTC (permalink / raw)
  To: u-boot

The original implementation select HS timing by default, add available
type selection for higher speed mode compatibility, such as hs200,
hs400, hs400es.

By the way, we assume that card run at 1.8V or 1.2V I/O when its timing
is ddr52/hs200/hs400(es).

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

 drivers/mmc/mmc.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 include/mmc.h     | 16 +++++++++++++++
 2 files changed, 74 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 72fc177..f5b2280 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -546,10 +546,62 @@ int mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value)
 
 }
 
+static u32 mmc_select_card_type(struct mmc *mmc, u8 *ext_csd)
+{
+	u8 card_type;
+	u32 host_caps, avail_type = 0;
+
+	card_type = ext_csd[EXT_CSD_CARD_TYPE];
+	host_caps = mmc->cfg->host_caps;
+
+	if ((host_caps & MMC_MODE_HS) &&
+	    (card_type & EXT_CSD_CARD_TYPE_26))
+		avail_type |= EXT_CSD_CARD_TYPE_26;
+
+	if ((host_caps & MMC_MODE_HS) &&
+	    (card_type & EXT_CSD_CARD_TYPE_52))
+		avail_type |= EXT_CSD_CARD_TYPE_52;
+
+	/*
+	 * For the moment, u-boot doesn't support signal voltage
+	 * switch, therefor we assume that host support ddr52
+	 * at 1.8v or 3.3v I/O(1.2v I/O not supported, hs200 and
+	 * hs400 are the same).
+	 */
+	if ((host_caps & MMC_MODE_DDR_52MHz) &&
+	    (card_type & EXT_CSD_CARD_TYPE_DDR_1_8V))
+		avail_type |= EXT_CSD_CARD_TYPE_DDR_1_8V;
+
+	if ((host_caps & MMC_MODE_HS200) &&
+	    (card_type & EXT_CSD_CARD_TYPE_HS200_1_8V))
+		avail_type |= EXT_CSD_CARD_TYPE_HS200_1_8V;
+
+	/*
+	 * If host can support HS400, it means that host can also
+	 * support HS200.
+	 */
+	if ((host_caps & MMC_MODE_HS400) &&
+	    (host_caps & MMC_MODE_8BIT) &&
+	    (card_type & EXT_CSD_CARD_TYPE_HS400_1_8V))
+		avail_type |= EXT_CSD_CARD_TYPE_HS200_1_8V |
+				EXT_CSD_CARD_TYPE_HS400_1_8V;
+
+	if ((host_caps & MMC_MODE_HS400ES) &&
+	    (host_caps & MMC_MODE_8BIT) &&
+	    ext_csd[EXT_CSD_STROBE_SUPPORT] &&
+	    (avail_type & EXT_CSD_CARD_TYPE_HS400_1_8V))
+		avail_type |= EXT_CSD_CARD_TYPE_HS200_1_8V |
+				EXT_CSD_CARD_TYPE_HS400_1_8V |
+				EXT_CSD_CARD_TYPE_HS400ES;
+
+	return avail_type;
+}
+
 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;
 
 	mmc->card_caps = 0;
@@ -569,8 +621,13 @@ static int mmc_change_freq(struct mmc *mmc)
 		return err;
 
 	cardtype = ext_csd[EXT_CSD_CARD_TYPE] & 0xf;
+	avail_type = mmc_select_card_type(mmc, ext_csd);
 
-	err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_HS_TIMING, 1);
+	if (avail_type & EXT_CSD_CARD_TYPE_HS)
+		err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL,
+				 EXT_CSD_HS_TIMING, 1);
+	else
+		err = -EINVAL;
 
 	if (err)
 		return err;
diff --git a/include/mmc.h b/include/mmc.h
index fad12d6..0bae1a1 100644
--- a/include/mmc.h
+++ b/include/mmc.h
@@ -58,6 +58,9 @@
 #define MMC_MODE_8BIT		(1 << 3)
 #define MMC_MODE_SPI		(1 << 4)
 #define MMC_MODE_DDR_52MHz	(1 << 5)
+#define MMC_MODE_HS200		(1 << 6)
+#define MMC_MODE_HS400		(1 << 7)
+#define MMC_MODE_HS400ES	(1 << 8)
 
 #define SD_DATA_4BIT	0x00040000
 
@@ -182,6 +185,7 @@
 #define EXT_CSD_BOOT_BUS_WIDTH		177
 #define EXT_CSD_PART_CONF		179	/* R/W */
 #define EXT_CSD_BUS_WIDTH		183	/* R/W */
+#define EXT_CSD_STROBE_SUPPORT		184	/* RO */
 #define EXT_CSD_HS_TIMING		185	/* R/W */
 #define EXT_CSD_REV			192	/* RO */
 #define EXT_CSD_CARD_TYPE		196	/* RO */
@@ -201,6 +205,18 @@
 
 #define EXT_CSD_CARD_TYPE_26	(1 << 0)	/* Card can run at 26MHz */
 #define EXT_CSD_CARD_TYPE_52	(1 << 1)	/* Card can run at 52MHz */
+#define EXT_CSD_CARD_TYPE_HS	(EXT_CSD_CARD_TYPE_26 | \
+				 EXT_CSD_CARD_TYPE_52)
+#define EXT_CSD_CARD_TYPE_HS200_1_8V	BIT(4)	/* Card can run at 200MHz */
+#define EXT_CSD_CARD_TYPE_HS200_1_2V	BIT(5)	/* Card can run at 200MHz */
+#define EXT_CSD_CARD_TYPE_HS200		(EXT_CSD_CARD_TYPE_HS200_1_8V | \
+					 EXT_CSD_CARD_TYPE_HS200_1_2V)
+#define EXT_CSD_CARD_TYPE_HS400_1_8V	BIT(6)	/* Card can run at 200MHz DDR, 1.8V */
+#define EXT_CSD_CARD_TYPE_HS400_1_2V	BIT(7)	/* Card can run at 200MHz DDR, 1.2V */
+#define EXT_CSD_CARD_TYPE_HS400		(EXT_CSD_CARD_TYPE_HS400_1_8V | \
+					 EXT_CSD_CARD_TYPE_HS400_1_2V)
+#define EXT_CSD_CARD_TYPE_HS400ES	BIT(8)	/* Card can run@HS400ES */
+
 #define EXT_CSD_CARD_TYPE_DDR_1_8V	(1 << 2)
 #define EXT_CSD_CARD_TYPE_DDR_1_2V	(1 << 3)
 #define EXT_CSD_CARD_TYPE_DDR_52	(EXT_CSD_CARD_TYPE_DDR_1_8V \
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2017-05-15  6:06 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-05-15  5:56 [U-Boot] [PATCH 01/33] mmc: select the available type from host_caps and card_caps Ziyuan Xu
2017-05-15  5:56 ` [U-Boot] [PATCH 02/33] mmc: add set_timing entry for timing selection Ziyuan Xu
2017-05-15  5:56 ` [U-Boot] [PATCH 03/33] mmc: xenon_sdhci: drop redundant timing definitions Ziyuan Xu
2017-05-15  5:56 ` [U-Boot] [PATCH 04/33] mmc: rework high speed mode selection Ziyuan Xu
2017-05-15  5:57 ` [U-Boot] [PATCH 05/33] mmc: sdhci: fix HISPD bit setting Ziyuan Xu
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

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.