linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/6] mmc: core: hs400(es) fix probe/init
@ 2020-12-08  6:18 Chris Ruehl
  2020-12-08  6:18 ` [PATCH 1/6] mmc: core: prepare hs400 update, code order Chris Ruehl
                   ` (7 more replies)
  0 siblings, 8 replies; 10+ messages in thread
From: Chris Ruehl @ 2020-12-08  6:18 UTC (permalink / raw)
  To: linux-mmc
  Cc: Ulf Hansson, Chris Ruehl, Wolfram Sang, Yoshihiro Shimoda,
	Ludovic Barre, Krishna Konda, linux-kernel, Jack

Fix the probe if hs400-1_8v / hs400-1_2v is used in the
dts and mmc-hs400-enhanced-strobe isn't set.
That was the first attemped, but it turns out that some
more cleanups and simplifications can be done.

* move mmc_select_hs400() in between hs200 & hs400es (preparation)
* make mmc_select_hs400() independent and move it out
  of the hs200. Run hs400 tuning inside mmc_select_hs400();
* merge hs400 with hs400es function
* remove mmc_select_hs400es function 
* remove mmc_hs200_tuning()
* cleanup host->caps2 for hs400-1_8(2)v 


Signed-off-by: Chris Ruehl <chris.ruehl@gtsys.com.hk>
---
Replace patch set [PATCH 0/3] mmc: core: hs400 fix probe

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

* [PATCH 1/6] mmc: core: prepare hs400 update, code order
  2020-12-08  6:18 [PATCH 0/6] mmc: core: hs400(es) fix probe/init Chris Ruehl
@ 2020-12-08  6:18 ` Chris Ruehl
  2020-12-08  6:18 ` [PATCH 2/6] mmc: core: make hs400 independent from hs200 init Chris Ruehl
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 10+ messages in thread
From: Chris Ruehl @ 2020-12-08  6:18 UTC (permalink / raw)
  To: linux-mmc
  Cc: Ulf Hansson, Chris Ruehl, Wolfram Sang, Yoshihiro Shimoda,
	Ludovic Barre, Krishna Konda, linux-kernel, Jack

This patch didn't change functionality just move
mmc_select_hs400() and mmc_hs200_to_hs400() between
mmc_select_hs400es() and mmc_select_hs200.
fix checkpatch --script warings.

Signed-off-by: Chris Ruehl <chris.ruehl@gtsys.com.hk>
---
 drivers/mmc/core/mmc.c | 184 ++++++++++++++++++++---------------------
 1 file changed, 92 insertions(+), 92 deletions(-)

diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index ff3063ce2acd..5477786aded8 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -1142,98 +1142,6 @@ static int mmc_select_hs_ddr(struct mmc_card *card)
 	return err;
 }
 
-static int mmc_select_hs400(struct mmc_card *card)
-{
-	struct mmc_host *host = card->host;
-	unsigned int max_dtr;
-	int err = 0;
-	u8 val;
-
-	/*
-	 * HS400 mode requires 8-bit bus width
-	 */
-	if (!(card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS400 &&
-	      host->ios.bus_width == MMC_BUS_WIDTH_8))
-		return 0;
-
-	/* Switch card to HS mode */
-	val = EXT_CSD_TIMING_HS;
-	err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
-			   EXT_CSD_HS_TIMING, val,
-			   card->ext_csd.generic_cmd6_time, 0,
-			   false, true);
-	if (err) {
-		pr_err("%s: switch to high-speed from hs200 failed, err:%d\n",
-			mmc_hostname(host), err);
-		return err;
-	}
-
-	/* Prepare host to downgrade to HS timing */
-	if (host->ops->hs400_downgrade)
-		host->ops->hs400_downgrade(host);
-
-	/* Set host controller to HS timing */
-	mmc_set_timing(host, MMC_TIMING_MMC_HS);
-
-	/* Reduce frequency to HS frequency */
-	max_dtr = card->ext_csd.hs_max_dtr;
-	mmc_set_clock(host, max_dtr);
-
-	err = mmc_switch_status(card, true);
-	if (err)
-		goto out_err;
-
-	if (host->ops->hs400_prepare_ddr)
-		host->ops->hs400_prepare_ddr(host);
-
-	/* Switch card to DDR */
-	err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
-			 EXT_CSD_BUS_WIDTH,
-			 EXT_CSD_DDR_BUS_WIDTH_8,
-			 card->ext_csd.generic_cmd6_time);
-	if (err) {
-		pr_err("%s: switch to bus width for hs400 failed, err:%d\n",
-			mmc_hostname(host), err);
-		return err;
-	}
-
-	/* Switch card to HS400 */
-	val = EXT_CSD_TIMING_HS400 |
-	      card->drive_strength << EXT_CSD_DRV_STR_SHIFT;
-	err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
-			   EXT_CSD_HS_TIMING, val,
-			   card->ext_csd.generic_cmd6_time, 0,
-			   false, true);
-	if (err) {
-		pr_err("%s: switch to hs400 failed, err:%d\n",
-			 mmc_hostname(host), err);
-		return err;
-	}
-
-	/* Set host controller to HS400 timing and frequency */
-	mmc_set_timing(host, MMC_TIMING_MMC_HS400);
-	mmc_set_bus_speed(card);
-
-	if (host->ops->hs400_complete)
-		host->ops->hs400_complete(host);
-
-	err = mmc_switch_status(card, true);
-	if (err)
-		goto out_err;
-
-	return 0;
-
-out_err:
-	pr_err("%s: %s failed, error %d\n", mmc_hostname(card->host),
-	       __func__, err);
-	return err;
-}
-
-int mmc_hs200_to_hs400(struct mmc_card *card)
-{
-	return mmc_select_hs400(card);
-}
-
 int mmc_hs400_to_hs200(struct mmc_card *card)
 {
 	struct mmc_host *host = card->host;
@@ -1425,6 +1333,98 @@ static int mmc_select_hs400es(struct mmc_card *card)
 	return err;
 }
 
+static int mmc_select_hs400(struct mmc_card *card)
+{
+	struct mmc_host *host = card->host;
+	unsigned int max_dtr;
+	int err = 0;
+	u8 val;
+
+	/*
+	 * HS400 mode requires 8-bit bus width
+	 */
+	if (!(card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS400 &&
+	      host->ios.bus_width == MMC_BUS_WIDTH_8))
+		return 0;
+
+	/* Switch card to HS mode */
+	val = EXT_CSD_TIMING_HS;
+	err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
+			   EXT_CSD_HS_TIMING, val,
+			   card->ext_csd.generic_cmd6_time, 0,
+			   false, true);
+	if (err) {
+		pr_err("%s: switch to high-speed from hs200 failed, err:%d\n",
+		       mmc_hostname(host), err);
+		return err;
+	}
+
+	/* Prepare host to downgrade to HS timing */
+	if (host->ops->hs400_downgrade)
+		host->ops->hs400_downgrade(host);
+
+	/* Set host controller to HS timing */
+	mmc_set_timing(host, MMC_TIMING_MMC_HS);
+
+	/* Reduce frequency to HS frequency */
+	max_dtr = card->ext_csd.hs_max_dtr;
+	mmc_set_clock(host, max_dtr);
+
+	err = mmc_switch_status(card, true);
+	if (err)
+		goto out_err;
+
+	if (host->ops->hs400_prepare_ddr)
+		host->ops->hs400_prepare_ddr(host);
+
+	/* Switch card to DDR */
+	err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
+			 EXT_CSD_BUS_WIDTH,
+			 EXT_CSD_DDR_BUS_WIDTH_8,
+			 card->ext_csd.generic_cmd6_time);
+	if (err) {
+		pr_err("%s: switch to bus width for hs400 failed, err:%d\n",
+		       mmc_hostname(host), err);
+		return err;
+	}
+
+	/* Switch card to HS400 */
+	val = EXT_CSD_TIMING_HS400 |
+	      card->drive_strength << EXT_CSD_DRV_STR_SHIFT;
+	err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
+			   EXT_CSD_HS_TIMING, val,
+			   card->ext_csd.generic_cmd6_time, 0,
+			   false, true);
+	if (err) {
+		pr_err("%s: switch to hs400 failed, err:%d\n",
+		       mmc_hostname(host), err);
+		return err;
+	}
+
+	/* Set host controller to HS400 timing and frequency */
+	mmc_set_timing(host, MMC_TIMING_MMC_HS400);
+	mmc_set_bus_speed(card);
+
+	if (host->ops->hs400_complete)
+		host->ops->hs400_complete(host);
+
+	err = mmc_switch_status(card, true);
+	if (err)
+		goto out_err;
+
+	return 0;
+
+out_err:
+	pr_err("%s: %s failed, error %d\n", mmc_hostname(card->host),
+	       __func__, err);
+	return err;
+}
+
+int mmc_hs200_to_hs400(struct mmc_card *card)
+{
+	return mmc_select_hs400(card);
+}
+
 /*
  * For device supporting HS200 mode, the following sequence
  * should be done before executing the tuning process.
-- 
2.20.1


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

* [PATCH 2/6] mmc: core: make hs400 independent from hs200 init
  2020-12-08  6:18 [PATCH 0/6] mmc: core: hs400(es) fix probe/init Chris Ruehl
  2020-12-08  6:18 ` [PATCH 1/6] mmc: core: prepare hs400 update, code order Chris Ruehl
@ 2020-12-08  6:18 ` Chris Ruehl
  2020-12-08  6:18 ` [PATCH 3/6] mmc: core: add enhanced strobe to mmc_select_hs400() Chris Ruehl
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 10+ messages in thread
From: Chris Ruehl @ 2020-12-08  6:18 UTC (permalink / raw)
  To: linux-mmc
  Cc: Ulf Hansson, Chris Ruehl, Wolfram Sang, Yoshihiro Shimoda,
	Ludovic Barre, Krishna Konda, linux-kernel, Jack

Move mmc_select_hs400() out from hs200 init path and make hs400
independent.

The patch makes quite some changes and needs to be reviewed carefully.

In function mmc_select_timing() call for mmc_select_hs400().
HS400 requires a host bus with of 8bit, if not supported we
return with -ENOTSUPP, there is no retry.
If the host controller can't switch to 8bit (dts: bus-width = <4>)
it can't recover on next power-up init failed.
Have the controller set to HS mode, make the hs400 tuning prepare
if any and run mmc tuning before switching to HS400.

This patch resolve the problem if hs400-1_8v is set but extended
strobe is not.

&sdhci { // eMMC
        bus-width = <8>;
        mmc-hs400-1_8v;
        // mmc-hs400-enhanced-strobe;
        non-removable;
        status = "okay";
};

[    1.775721] mmc1: CQHCI version 5.10
[    1.802342] mmc1: SDHCI controller on fe330000.sdhci [fe330000.sdhci] using ADMA
[    2.007581] mmc1: mmc_select_hs200 failed, error -110
[    2.007589] mmc1: error -110 whilst initialising MMC card
[    2.413559] mmc1: mmc_select_hs200 failed, error -110
[    2.413562] mmc1: error -110 whilst initialising MMC card
[    3.183343] mmc1: Command Queue Engine enabled
[    3.183355] mmc1: new HS400 MMC card at address 0001
[    3.197163] mmcblk1: mmc1:0001 DG4008 7.28 GiB
[    3.197256] mmcblk1boot0: mmc1:0001 DG4008 partition 1 4.00 MiB
[    3.197360] mmcblk1boot1: mmc1:0001 DG4008 partition 2 4.00 MiB
[    3.197360] mmcblk1boot1: mmc1:0001 DG4008 partition 2 4.00 MiB
[    3.197479] mmcblk1rpmb: mmc1:0001 DG4008 partition 3 4.00 MiB, chardev (242:0)

[    1.743386] mmc1: CQHCI version 5.10
[    1.769952] mmc1: SDHCI controller on fe330000.sdhci [fe330000.sdhci] using ADMA
[    1.846223] mmc1: Command Queue Engine enabled
[    1.846230] mmc1: new HS400 MMC card at address 0001
[    1.846557] mmcblk1: mmc1:0001 DG4008 7.28 GiB
[    1.846650] mmcblk1boot0: mmc1:0001 DG4008 partition 1 4.00 MiB
[    1.846742] mmcblk1boot1: mmc1:0001 DG4008 partition 2 4.00 MiB
[    1.846825] mmcblk1rpmb: mmc1:0001 DG4008 partition 3 4.00 MiB, chardev (242:0)

Tested with rk3399 customized board.

Signed-off-by: Chris Ruehl <chris.ruehl@gtsys.com.hk>
---
 drivers/mmc/core/mmc.c | 61 +++++++++++++++++++++++++++++++++++-------
 1 file changed, 52 insertions(+), 9 deletions(-)

diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index 5477786aded8..e7b4de3d4f47 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -1337,15 +1337,46 @@ static int mmc_select_hs400(struct mmc_card *card)
 {
 	struct mmc_host *host = card->host;
 	unsigned int max_dtr;
-	int err = 0;
+	int err = -EINVAL;
 	u8 val;
 
 	/*
-	 * HS400 mode requires 8-bit bus width
+	 * HS400 mode requires host 8-bit bus width
 	 */
-	if (!(card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS400 &&
-	      host->ios.bus_width == MMC_BUS_WIDTH_8))
-		return 0;
+	if (!(host->caps & MMC_CAP_8_BIT_DATA)) {
+		pr_err("%s: host not support hs400 8bit\n",
+		       mmc_hostname(host));
+		return -EOPNOTSUPP;
+	}
+
+	/*
+	 * Below is a change from previous logic.
+	 * mmc_avail_type vccq voltage set in dts, it can be 1_2v or 1_8v
+	 * but not both.
+	 */
+	if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS400_1_2V) {
+		err = mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_120);
+	} else if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS400_1_8V) {
+		err = mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180);
+	} else {
+		pr_err("%s: hs400 unsupported vccq voltage, err:%d\n",
+		       mmc_hostname(host), -EOPNOTSUPP);
+		return -EOPNOTSUPP;
+	}
+
+	/* Failed set 1_2v or 1_8v try again during next card power cycle */
+	if (err)
+		return err;
+
+	mmc_select_driver_type(card);
+
+	err = mmc_select_bus_width(card);
+	if (err != MMC_BUS_WIDTH_8) {
+		pr_err("%s: switch to 8bit bus width failed, err:%d\n",
+		       mmc_hostname(host), err);
+		err = err < 0 ? err : -EOPNOTSUPP;
+		goto out_err;
+	}
 
 	/* Switch card to HS mode */
 	val = EXT_CSD_TIMING_HS;
@@ -1388,6 +1419,18 @@ static int mmc_select_hs400(struct mmc_card *card)
 		return err;
 	}
 
+	/* HS400 prepare and execute tuning  */
+	host->doing_init_tune = 1;
+	if (host->ops->prepare_hs400_tuning)
+		host->ops->prepare_hs400_tuning(host, &host->ios);
+	err = mmc_execute_tuning(card);
+	host->doing_init_tune = 0;
+	if (err) {
+		pr_err("%s: hs400 tuning failed, err:%d\n",
+		       mmc_hostname(host), err);
+		return err;
+	}
+
 	/* Switch card to HS400 */
 	val = EXT_CSD_TIMING_HS400 |
 	      card->drive_strength << EXT_CSD_DRV_STR_SHIFT;
@@ -1496,7 +1539,7 @@ static int mmc_select_hs200(struct mmc_card *card)
 }
 
 /*
- * Activate High Speed, HS200 or HS400ES mode if supported.
+ * Activate High Speed, HS200 ,HS400 or HS400ES mode if supported.
  */
 static int mmc_select_timing(struct mmc_card *card)
 {
@@ -1507,6 +1550,8 @@ static int mmc_select_timing(struct mmc_card *card)
 
 	if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS400ES)
 		err = mmc_select_hs400es(card);
+	else if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS400)
+		err = mmc_select_hs400(card);
 	else if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS200)
 		err = mmc_select_hs200(card);
 	else if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS)
@@ -1766,15 +1811,13 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
 		host->doing_init_tune = 1;
 
 		err = mmc_hs200_tuning(card);
-		if (!err)
-			err = mmc_select_hs400(card);
 
 		host->doing_init_tune = 0;
 
 		if (err)
 			goto free_card;
 
-	} else if (!mmc_card_hs400es(card)) {
+	} else if (!mmc_card_hs400es(card) && !mmc_card_hs400(card)) {
 		/* Select the desired bus width optionally */
 		err = mmc_select_bus_width(card);
 		if (err > 0 && mmc_card_hs(card)) {
-- 
2.20.1


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

* [PATCH 3/6] mmc: core: add enhanced strobe to mmc_select_hs400()
  2020-12-08  6:18 [PATCH 0/6] mmc: core: hs400(es) fix probe/init Chris Ruehl
  2020-12-08  6:18 ` [PATCH 1/6] mmc: core: prepare hs400 update, code order Chris Ruehl
  2020-12-08  6:18 ` [PATCH 2/6] mmc: core: make hs400 independent from hs200 init Chris Ruehl
@ 2020-12-08  6:18 ` Chris Ruehl
  2020-12-08  6:18 ` [PATCH 4/6] mmc: core: remove mmc_select_hs400es() Chris Ruehl
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 10+ messages in thread
From: Chris Ruehl @ 2020-12-08  6:18 UTC (permalink / raw)
  To: linux-mmc
  Cc: Ulf Hansson, Chris Ruehl, Wolfram Sang, Yoshihiro Shimoda,
	Ludovic Barre, Krishna Konda, linux-kernel, Jack

Function mmc_select_hs400() and mmc_select_hs400es have almost
identical code it seems okay to merge them.
Add the function calls for enhanced strobe to mmc_select_hs400 and
add  a bool variable to the function call to enable them if HS400ES
is selected.
mmc_select_hs400es() becomes obsolate and can be removed.

Signed-off-by: Chris Ruehl <chris.ruehl@gtsys.com.hk>
---
 drivers/mmc/core/mmc.c | 20 +++++++++++++++-----
 1 file changed, 15 insertions(+), 5 deletions(-)

diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index e7b4de3d4f47..84c09d9e0317 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -1333,7 +1333,7 @@ static int mmc_select_hs400es(struct mmc_card *card)
 	return err;
 }
 
-static int mmc_select_hs400(struct mmc_card *card)
+static int mmc_select_hs400(struct mmc_card *card, bool enhancedstrobe)
 {
 	struct mmc_host *host = card->host;
 	unsigned int max_dtr;
@@ -1409,9 +1409,12 @@ static int mmc_select_hs400(struct mmc_card *card)
 		host->ops->hs400_prepare_ddr(host);
 
 	/* Switch card to DDR */
+	val = EXT_CSD_DDR_BUS_WIDTH_8;
+	if (enhancedstrobe)
+		val |= EXT_CSD_BUS_WIDTH_STROBE;
 	err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
 			 EXT_CSD_BUS_WIDTH,
-			 EXT_CSD_DDR_BUS_WIDTH_8,
+			 val,
 			 card->ext_csd.generic_cmd6_time);
 	if (err) {
 		pr_err("%s: switch to bus width for hs400 failed, err:%d\n",
@@ -1451,6 +1454,13 @@ static int mmc_select_hs400(struct mmc_card *card)
 	if (host->ops->hs400_complete)
 		host->ops->hs400_complete(host);
 
+	if (enhancedstrobe) {
+		/* Controller enable enhanced strobe function */
+		host->ios.enhanced_strobe = true;
+		if (host->ops->hs400_enhanced_strobe)
+			host->ops->hs400_enhanced_strobe(host, &host->ios);
+	}
+
 	err = mmc_switch_status(card, true);
 	if (err)
 		goto out_err;
@@ -1465,7 +1475,7 @@ static int mmc_select_hs400(struct mmc_card *card)
 
 int mmc_hs200_to_hs400(struct mmc_card *card)
 {
-	return mmc_select_hs400(card);
+	return mmc_select_hs400(card, false);
 }
 
 /*
@@ -1549,9 +1559,9 @@ static int mmc_select_timing(struct mmc_card *card)
 		goto bus_speed;
 
 	if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS400ES)
-		err = mmc_select_hs400es(card);
+		err = mmc_select_hs400(card, true);
 	else if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS400)
-		err = mmc_select_hs400(card);
+		err = mmc_select_hs400(card, false);
 	else if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS200)
 		err = mmc_select_hs200(card);
 	else if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS)
-- 
2.20.1


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

* [PATCH 4/6] mmc: core: remove mmc_select_hs400es()
  2020-12-08  6:18 [PATCH 0/6] mmc: core: hs400(es) fix probe/init Chris Ruehl
                   ` (2 preceding siblings ...)
  2020-12-08  6:18 ` [PATCH 3/6] mmc: core: add enhanced strobe to mmc_select_hs400() Chris Ruehl
@ 2020-12-08  6:18 ` Chris Ruehl
  2020-12-08  6:18 ` [PATCH 5/6] mmc: core: simplify hs200 tuning Chris Ruehl
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 10+ messages in thread
From: Chris Ruehl @ 2020-12-08  6:18 UTC (permalink / raw)
  To: linux-mmc
  Cc: Ulf Hansson, Chris Ruehl, Wolfram Sang, Yoshihiro Shimoda,
	Ludovic Barre, Krishna Konda, linux-kernel, Jack

Enhanced strobe function had been merged in mmc_select_hs400();
mmc_select_hs400es() is obsolate and removed.

Signed-off-by: Chris Ruehl <chris.ruehl@gtsys.com.hk>
---
 drivers/mmc/core/mmc.c | 94 ------------------------------------------
 1 file changed, 94 deletions(-)

diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index 84c09d9e0317..f11562b58e89 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -1239,100 +1239,6 @@ static void mmc_select_driver_type(struct mmc_card *card)
 		mmc_set_driver_type(card->host, drv_type);
 }
 
-static int mmc_select_hs400es(struct mmc_card *card)
-{
-	struct mmc_host *host = card->host;
-	int err = -EINVAL;
-	u8 val;
-
-	if (!(host->caps & MMC_CAP_8_BIT_DATA)) {
-		err = -ENOTSUPP;
-		goto out_err;
-	}
-
-	if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS400_1_2V)
-		err = mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_120);
-
-	if (err && card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS400_1_8V)
-		err = mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180);
-
-	/* If fails try again during next card power cycle */
-	if (err)
-		goto out_err;
-
-	err = mmc_select_bus_width(card);
-	if (err != MMC_BUS_WIDTH_8) {
-		pr_err("%s: switch to 8bit bus width failed, err:%d\n",
-			mmc_hostname(host), err);
-		err = err < 0 ? err : -ENOTSUPP;
-		goto out_err;
-	}
-
-	/* Switch card to HS mode */
-	err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
-			   EXT_CSD_HS_TIMING, EXT_CSD_TIMING_HS,
-			   card->ext_csd.generic_cmd6_time, 0,
-			   false, true);
-	if (err) {
-		pr_err("%s: switch to hs for hs400es failed, err:%d\n",
-			mmc_hostname(host), err);
-		goto out_err;
-	}
-
-	mmc_set_timing(host, MMC_TIMING_MMC_HS);
-	err = mmc_switch_status(card, true);
-	if (err)
-		goto out_err;
-
-	mmc_set_clock(host, card->ext_csd.hs_max_dtr);
-
-	/* Switch card to DDR with strobe bit */
-	val = EXT_CSD_DDR_BUS_WIDTH_8 | EXT_CSD_BUS_WIDTH_STROBE;
-	err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
-			 EXT_CSD_BUS_WIDTH,
-			 val,
-			 card->ext_csd.generic_cmd6_time);
-	if (err) {
-		pr_err("%s: switch to bus width for hs400es failed, err:%d\n",
-			mmc_hostname(host), err);
-		goto out_err;
-	}
-
-	mmc_select_driver_type(card);
-
-	/* Switch card to HS400 */
-	val = EXT_CSD_TIMING_HS400 |
-	      card->drive_strength << EXT_CSD_DRV_STR_SHIFT;
-	err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
-			   EXT_CSD_HS_TIMING, val,
-			   card->ext_csd.generic_cmd6_time, 0,
-			   false, true);
-	if (err) {
-		pr_err("%s: switch to hs400es failed, err:%d\n",
-			mmc_hostname(host), err);
-		goto out_err;
-	}
-
-	/* Set host controller to HS400 timing and frequency */
-	mmc_set_timing(host, MMC_TIMING_MMC_HS400);
-
-	/* Controller enable enhanced strobe function */
-	host->ios.enhanced_strobe = true;
-	if (host->ops->hs400_enhanced_strobe)
-		host->ops->hs400_enhanced_strobe(host, &host->ios);
-
-	err = mmc_switch_status(card, true);
-	if (err)
-		goto out_err;
-
-	return 0;
-
-out_err:
-	pr_err("%s: %s failed, error %d\n", mmc_hostname(card->host),
-	       __func__, err);
-	return err;
-}
-
 static int mmc_select_hs400(struct mmc_card *card, bool enhancedstrobe)
 {
 	struct mmc_host *host = card->host;
-- 
2.20.1


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

* [PATCH 5/6] mmc: core: simplify hs200 tuning
  2020-12-08  6:18 [PATCH 0/6] mmc: core: hs400(es) fix probe/init Chris Ruehl
                   ` (3 preceding siblings ...)
  2020-12-08  6:18 ` [PATCH 4/6] mmc: core: remove mmc_select_hs400es() Chris Ruehl
@ 2020-12-08  6:18 ` Chris Ruehl
  2020-12-08  6:18 ` [PATCH 6/6] mmc: core: with mmc-hs400-1_8(2)v not add MMC_CAP2_HS200* to host->caps2 Chris Ruehl
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 10+ messages in thread
From: Chris Ruehl @ 2020-12-08  6:18 UTC (permalink / raw)
  To: linux-mmc
  Cc: Ulf Hansson, Chris Ruehl, Wolfram Sang, Yoshihiro Shimoda,
	Ludovic Barre, Krishna Konda, linux-kernel, Jack

Since the host->ops->prepare_hs400_tuning had been moved to
mmc_select_hs400() the tuning for hs200 can simplify and
the function mmc_hs200_tuning() can be removed.

Signed-off-by: Chris Ruehl <chris.ruehl@gtsys.com.hk>
---
 drivers/mmc/core/mmc.c | 22 +---------------------
 1 file changed, 1 insertion(+), 21 deletions(-)

diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index f11562b58e89..6ef6029b6948 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -1485,26 +1485,6 @@ static int mmc_select_timing(struct mmc_card *card)
 	return 0;
 }
 
-/*
- * Execute tuning sequence to seek the proper bus operating
- * conditions for HS200 and HS400, which sends CMD21 to the device.
- */
-static int mmc_hs200_tuning(struct mmc_card *card)
-{
-	struct mmc_host *host = card->host;
-
-	/*
-	 * Timing should be adjusted to the HS400 target
-	 * operation frequency for tuning process
-	 */
-	if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS400 &&
-	    host->ios.bus_width == MMC_BUS_WIDTH_8)
-		if (host->ops->prepare_hs400_tuning)
-			host->ops->prepare_hs400_tuning(host, &host->ios);
-
-	return mmc_execute_tuning(card);
-}
-
 /*
  * Handle the detection and initialisation of a card.
  *
@@ -1726,7 +1706,7 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
 	if (mmc_card_hs200(card)) {
 		host->doing_init_tune = 1;
 
-		err = mmc_hs200_tuning(card);
+		err = mmc_execute_tuning(card);
 
 		host->doing_init_tune = 0;
 
-- 
2.20.1


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

* [PATCH 6/6] mmc: core: with mmc-hs400-1_8(2)v not add MMC_CAP2_HS200* to host->caps2
  2020-12-08  6:18 [PATCH 0/6] mmc: core: hs400(es) fix probe/init Chris Ruehl
                   ` (4 preceding siblings ...)
  2020-12-08  6:18 ` [PATCH 5/6] mmc: core: simplify hs200 tuning Chris Ruehl
@ 2020-12-08  6:18 ` Chris Ruehl
  2021-02-01 10:52   ` Ulf Hansson
  2020-12-12  1:01 ` [PATCH 0/6] mmc: core: hs400(es) fix probe/init Chris Ruehl
  2021-01-22 12:40 ` Ulf Hansson
  7 siblings, 1 reply; 10+ messages in thread
From: Chris Ruehl @ 2020-12-08  6:18 UTC (permalink / raw)
  To: linux-mmc
  Cc: Ulf Hansson, Chris Ruehl, Wolfram Sang, Yoshihiro Shimoda,
	Ludovic Barre, Krishna Konda, linux-kernel, Jack

When set mmc-hs400-1_8(2)v in dts, hs200 capabilities are not checked
in the mmc logic. Thus cleanup and remove MMC_CAP2_HS200_1_8V_SDR /
MMC_CAP2_HS200_1_2V_SDR from host->caps2.

Signed-off-by: Chris Ruehl <chris.ruehl@gtsys.com.hk>
---
 drivers/mmc/core/host.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c
index 96b2ca1f1b06..46fde60a2372 100644
--- a/drivers/mmc/core/host.c
+++ b/drivers/mmc/core/host.c
@@ -295,9 +295,9 @@ int mmc_of_parse(struct mmc_host *host)
 	if (device_property_read_bool(dev, "mmc-hs200-1_2v"))
 		host->caps2 |= MMC_CAP2_HS200_1_2V_SDR;
 	if (device_property_read_bool(dev, "mmc-hs400-1_8v"))
-		host->caps2 |= MMC_CAP2_HS400_1_8V | MMC_CAP2_HS200_1_8V_SDR;
+		host->caps2 |= MMC_CAP2_HS400_1_8V;
 	if (device_property_read_bool(dev, "mmc-hs400-1_2v"))
-		host->caps2 |= MMC_CAP2_HS400_1_2V | MMC_CAP2_HS200_1_2V_SDR;
+		host->caps2 |= MMC_CAP2_HS400_1_2V;
 	if (device_property_read_bool(dev, "mmc-hs400-enhanced-strobe"))
 		host->caps2 |= MMC_CAP2_HS400_ES;
 	if (device_property_read_bool(dev, "no-sdio"))
-- 
2.20.1


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

* Re: [PATCH 0/6] mmc: core: hs400(es) fix probe/init
  2020-12-08  6:18 [PATCH 0/6] mmc: core: hs400(es) fix probe/init Chris Ruehl
                   ` (5 preceding siblings ...)
  2020-12-08  6:18 ` [PATCH 6/6] mmc: core: with mmc-hs400-1_8(2)v not add MMC_CAP2_HS200* to host->caps2 Chris Ruehl
@ 2020-12-12  1:01 ` Chris Ruehl
  2021-01-22 12:40 ` Ulf Hansson
  7 siblings, 0 replies; 10+ messages in thread
From: Chris Ruehl @ 2020-12-12  1:01 UTC (permalink / raw)
  To: linux-mmc
  Cc: Ulf Hansson, Wolfram Sang, Yoshihiro Shimoda, Ludovic Barre,
	Krishna Konda, linux-kernel, Jack

No Comments ?

Chris

On 8/12/2020 2:18 pm, Chris Ruehl wrote:
> Fix the probe if hs400-1_8v / hs400-1_2v is used in the
> dts and mmc-hs400-enhanced-strobe isn't set.
> That was the first attemped, but it turns out that some
> more cleanups and simplifications can be done.
> 
> * move mmc_select_hs400() in between hs200 & hs400es (preparation)
> * make mmc_select_hs400() independent and move it out
>    of the hs200. Run hs400 tuning inside mmc_select_hs400();
> * merge hs400 with hs400es function
> * remove mmc_select_hs400es function
> * remove mmc_hs200_tuning()
> * cleanup host->caps2 for hs400-1_8(2)v
> 
> 
> Signed-off-by: Chris Ruehl <chris.ruehl@gtsys.com.hk>
> ---
> Replace patch set [PATCH 0/3] mmc: core: hs400 fix probe
> 

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

* Re: [PATCH 0/6] mmc: core: hs400(es) fix probe/init
  2020-12-08  6:18 [PATCH 0/6] mmc: core: hs400(es) fix probe/init Chris Ruehl
                   ` (6 preceding siblings ...)
  2020-12-12  1:01 ` [PATCH 0/6] mmc: core: hs400(es) fix probe/init Chris Ruehl
@ 2021-01-22 12:40 ` Ulf Hansson
  7 siblings, 0 replies; 10+ messages in thread
From: Ulf Hansson @ 2021-01-22 12:40 UTC (permalink / raw)
  To: Chris Ruehl, Adrian Hunter
  Cc: linux-mmc, Wolfram Sang, Yoshihiro Shimoda, Ludovic Barre,
	Krishna Konda, Linux Kernel Mailing List, Jack

+ Adrian

On Tue, 8 Dec 2020 at 07:19, Chris Ruehl <chris.ruehl@gtsys.com.hk> wrote:
>
> Fix the probe if hs400-1_8v / hs400-1_2v is used in the
> dts and mmc-hs400-enhanced-strobe isn't set.
> That was the first attemped, but it turns out that some
> more cleanups and simplifications can be done.

My apologies for the delay with reviewing. I have looped in Adrian as
well, as he might have some input to our discussion.

Before I go into doing a detailed review, I want to make sure I
understand the problem correctly.

Are you saying that switching to eMMC HS400 mode doesn't work, unless
the enhanced strobe is supported, no? Or is this a DT only related
problem?

In any case, the main point with mmc_hs400_to_hs200() is to prepare
for tuning to run in HS200 mode (it's getting called from
mmc_retune()). In other words, there *should* be no need to support
enhanced strobe to support hs400, but I might be missing something.

In particular, the following commit could be of interest for you:

6376f69d20a6905c1d83be451065f70200490b98
Author: Adrian Hunter <adrian.hunter@intel.com>
Date:   Thu May 7 13:10:20 2015 +0300
mmc: core: Add support for HS400 re-tuning

>
> * move mmc_select_hs400() in between hs200 & hs400es (preparation)
> * make mmc_select_hs400() independent and move it out
>   of the hs200. Run hs400 tuning inside mmc_select_hs400();
> * merge hs400 with hs400es function
> * remove mmc_select_hs400es function
> * remove mmc_hs200_tuning()
> * cleanup host->caps2 for hs400-1_8(2)v
>
>
> Signed-off-by: Chris Ruehl <chris.ruehl@gtsys.com.hk>
> ---
> Replace patch set [PATCH 0/3] mmc: core: hs400 fix probe

Kind regards
Uffe

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

* Re: [PATCH 6/6] mmc: core: with mmc-hs400-1_8(2)v not add MMC_CAP2_HS200* to host->caps2
  2020-12-08  6:18 ` [PATCH 6/6] mmc: core: with mmc-hs400-1_8(2)v not add MMC_CAP2_HS200* to host->caps2 Chris Ruehl
@ 2021-02-01 10:52   ` Ulf Hansson
  0 siblings, 0 replies; 10+ messages in thread
From: Ulf Hansson @ 2021-02-01 10:52 UTC (permalink / raw)
  To: Chris Ruehl
  Cc: linux-mmc, Wolfram Sang, Yoshihiro Shimoda, Ludovic Barre,
	Krishna Konda, Linux Kernel Mailing List, Jack

On Tue, 8 Dec 2020 at 07:19, Chris Ruehl <chris.ruehl@gtsys.com.hk> wrote:
>
> When set mmc-hs400-1_8(2)v in dts, hs200 capabilities are not checked
> in the mmc logic. Thus cleanup and remove MMC_CAP2_HS200_1_8V_SDR /
> MMC_CAP2_HS200_1_2V_SDR from host->caps2.

I had another look at this - and I am struggling to get a grip of the
problem you are trying to solve, sorry. Please try to clarify things
through more descriptive commit messages.

*Plain* HS400 mode does seem to require HS200 mode, because tuning
needs to happen in HS200 mode. HS400 mode with enhanced strobe being
supported, doesn't need HS200 to be supported as tuning isn't done in
HS200 mode.

In your case, the controller supports HS400 mode in (1.8V or 1.2V)
with enhanced strobe, but not HS200 mode, correct?

Then because of the code that runs the initialization for the eMMC
card, we end up switching to HS200 mode prior enabling HS400 ES mode,
which causes problems in the driver/controller for your case, correct?

>
> Signed-off-by: Chris Ruehl <chris.ruehl@gtsys.com.hk>
> ---
>  drivers/mmc/core/host.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c
> index 96b2ca1f1b06..46fde60a2372 100644
> --- a/drivers/mmc/core/host.c
> +++ b/drivers/mmc/core/host.c
> @@ -295,9 +295,9 @@ int mmc_of_parse(struct mmc_host *host)
>         if (device_property_read_bool(dev, "mmc-hs200-1_2v"))
>                 host->caps2 |= MMC_CAP2_HS200_1_2V_SDR;
>         if (device_property_read_bool(dev, "mmc-hs400-1_8v"))
> -               host->caps2 |= MMC_CAP2_HS400_1_8V | MMC_CAP2_HS200_1_8V_SDR;
> +               host->caps2 |= MMC_CAP2_HS400_1_8V;
>         if (device_property_read_bool(dev, "mmc-hs400-1_2v"))
> -               host->caps2 |= MMC_CAP2_HS400_1_2V | MMC_CAP2_HS200_1_2V_SDR;
> +               host->caps2 |= MMC_CAP2_HS400_1_2V;
>         if (device_property_read_bool(dev, "mmc-hs400-enhanced-strobe"))
>                 host->caps2 |= MMC_CAP2_HS400_ES;
>         if (device_property_read_bool(dev, "no-sdio"))
> --
> 2.20.1
>

Kind regards
Uffe

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

end of thread, other threads:[~2021-02-01 10:55 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-12-08  6:18 [PATCH 0/6] mmc: core: hs400(es) fix probe/init Chris Ruehl
2020-12-08  6:18 ` [PATCH 1/6] mmc: core: prepare hs400 update, code order Chris Ruehl
2020-12-08  6:18 ` [PATCH 2/6] mmc: core: make hs400 independent from hs200 init Chris Ruehl
2020-12-08  6:18 ` [PATCH 3/6] mmc: core: add enhanced strobe to mmc_select_hs400() Chris Ruehl
2020-12-08  6:18 ` [PATCH 4/6] mmc: core: remove mmc_select_hs400es() Chris Ruehl
2020-12-08  6:18 ` [PATCH 5/6] mmc: core: simplify hs200 tuning Chris Ruehl
2020-12-08  6:18 ` [PATCH 6/6] mmc: core: with mmc-hs400-1_8(2)v not add MMC_CAP2_HS200* to host->caps2 Chris Ruehl
2021-02-01 10:52   ` Ulf Hansson
2020-12-12  1:01 ` [PATCH 0/6] mmc: core: hs400(es) fix probe/init Chris Ruehl
2021-01-22 12:40 ` Ulf Hansson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).