All of lore.kernel.org
 help / color / mirror / Atom feed
From: Simon Horman <horms+renesas@verge.net.au>
To: Wolfram Sang <wsa+renesas@sang-engineering.com>,
	Ulf Hansson <ulf.hansson@linaro.org>
Cc: Magnus Damm <magnus.damm@gmail.com>,
	linux-mmc@vger.kernel.org, linux-renesas-soc@vger.kernel.org,
	Simon Horman <horms+renesas@verge.net.au>
Subject: [PATCH v4 2/4] mmc: core: more fine-grained hooks for HS400 tuning
Date: Wed, 18 Apr 2018 11:56:58 +0200	[thread overview]
Message-ID: <20180418095700.29948-3-horms+renesas@verge.net.au> (raw)
In-Reply-To: <20180418095700.29948-1-horms+renesas@verge.net.au>

This adds two new HS400 tuning operations:
* prepare_hs400_tuning_downgrade
* complete_hs400_tuning

These supplement the existing HS400 operation:
* prepare_hs400_tuning

This is motivated by a requirement of Renesas SDHI for the following:
1. Disabling SCC before selecting to HS if selection of HS400 has occurred.
   This can be done in an implementation of prepare_hs400_tuning_downgrade
2. Updating registers after switching to HS400
   This can be done in an implementation of complete_hs400_tuning

After this patch the call sequence is as follows:

* Initial tuning
  i. prepare_hs400_tuning
  2. Tuning procedure
  3. Select HS400
  4. complete_hs400_tuning

* Retune
  1. prepare_hs400_tuning_downgrade
  2. Select HS200
  3. prepare_hs400_tuning
  4. Tuning procedure
  5. Select HS400
  6. complete_hs400_tuning

If prepare_hs400_tuning or complete_hs400_tuning are not implemented they
are not called. And if neither are called the procedure is the same as
before this patch.

Design consideration: In the case of Renesas SDHI it is likely that
prepare_hs400_tuning_downgrade and prepare_hs400_tuning could be combined
if the latter was called before selecting HS200 during tuning. When I say
likely, I believe it matches my understanding of the hardware. However, I
did not test this as I am entirely unsure if moving the
prepare_hs400_tuning call would work for other hardware that uses this
operation and I am in no position to test such hardware.

Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
---
v4
* New patch
---
 drivers/mmc/core/host.c  | 13 ++++++++++++-
 drivers/mmc/core/mmc.c   | 19 ++++++++++++++-----
 include/linux/mmc/host.h | 26 +++++++++++++++++++++++++-
 3 files changed, 51 insertions(+), 7 deletions(-)

diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c
index 64b03d6eaf18..5e60df7ca11f 100644
--- a/drivers/mmc/core/host.c
+++ b/drivers/mmc/core/host.c
@@ -138,6 +138,10 @@ int mmc_retune(struct mmc_host *host)
 	host->doing_retune = 1;
 
 	if (host->ios.timing == MMC_TIMING_MMC_HS400) {
+		if (host->ops->prepare_hs400_tuning_downgrade)
+			host->ops->prepare_hs400_tuning_downgrade(host,
+								  &host->ios);
+
 		err = mmc_hs400_to_hs200(host->card);
 		if (err)
 			goto out;
@@ -152,8 +156,15 @@ int mmc_retune(struct mmc_host *host)
 	if (err)
 		goto out;
 
-	if (return_to_hs400)
+	if (return_to_hs400) {
 		err = mmc_hs200_to_hs400(host->card);
+		if (err)
+			goto out;
+
+		if (host->ops->complete_hs400_tuning)
+			host->ops->complete_hs400_tuning(host, &host->ios);
+	}
+
 out:
 	host->doing_retune = 0;
 
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index 099b327e10ca..a108a1a3e27f 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -1508,22 +1508,31 @@ static int mmc_select_timing(struct mmc_card *card)
 static int mmc_hs200_tuning(struct mmc_card *card)
 {
 	struct mmc_host *host = card->host;
+	bool run_hs400_ops;
 	int err;
 
+	run_hs400_ops = card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS400 &&
+		host->ios.bus_width == MMC_BUS_WIDTH_8;
+
 	/*
 	 * 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);
+	if (run_hs400_ops && host->ops->prepare_hs400_tuning)
+		host->ops->prepare_hs400_tuning(host, &host->ios);
 
 	err = mmc_execute_tuning(card);
 	if (err)
 		return err;
 
-	return mmc_select_hs400(card);
+	err = mmc_select_hs400(card);
+	if (err)
+		return err;
+
+	if (run_hs400_ops && host->ops->complete_hs400_tuning)
+		host->ops->complete_hs400_tuning(host, &host->ios);
+
+	return 0;
 }
 
 /*
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index 85146235231e..5d3ae1071d2f 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -143,8 +143,32 @@ struct mmc_host_ops {
 	/* The tuning command opcode value is different for SD and eMMC cards */
 	int	(*execute_tuning)(struct mmc_host *host, u32 opcode);
 
-	/* Prepare HS400 target operating frequency depending host driver */
+	/* Prepare for HS400 downgrade during tuning of target operating frequency depending on host driver
+	 * If provided and retuning is in progress, this is called before:
+	 * 1. Switching from HS400 to HS200; which preceeds
+	 * 2. Calling .prepare_hs400_tuning, if present; which preceeds
+	 * 3. The HS400 tuning procedure
+	 */
+	void	(*prepare_hs400_tuning_downgrade)(struct mmc_host *host, struct mmc_ios *ios);
+
+	/* Prepare for tuning HS400 target operating frequency depending on host driver
+	 * If provided, this called:
+	 * - In the case that retuning is in progress, after:
+	 *   1. .prepare_hs400_tuning_downgrade(), if present
+	 *   2. Switching from HS400 to HS200
+	 * - And in any case before:
+	 *   3. The HS400 tuning procedure
+	 */
+
 	int	(*prepare_hs400_tuning)(struct mmc_host *host, struct mmc_ios *ios);
+
+	/* Complete tuning HS400 target operating frequency depending host driver
+	 * If provided, this is called after:
+	 * 1. The HS400 tuning procedure
+	 * 2. Switching from HS200 to HS400
+	 */
+	void	(*complete_hs400_tuning)(struct mmc_host *host, struct mmc_ios *ios);
+
 	/* Prepare enhanced strobe depending host driver */
 	void	(*hs400_enhanced_strobe)(struct mmc_host *host,
 					 struct mmc_ios *ios);
-- 
2.11.0

  parent reply	other threads:[~2018-04-18  9:57 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-04-18  9:56 [PATCH v4 0/4] mmc: renesas_sdhi: add eMMC HS400 mode support Simon Horman
2018-04-18  9:56 ` [PATCH v4 1/4] mmc: core: select HS400 from HS200 tuning function Simon Horman
2018-04-18  9:56 ` Simon Horman [this message]
2018-05-22 14:32   ` [PATCH v4 2/4] mmc: core: more fine-grained hooks for HS400 tuning Ulf Hansson
2018-05-28 12:39     ` Simon Horman
2018-04-18  9:56 ` [PATCH v4 3/4] mmc: tmio: add eMMC HS400 mode support Simon Horman
2018-04-18  9:57 ` [PATCH v4 4/4] mmc: renesas_sdhi: " Simon Horman
2018-05-13  8:23 ` [PATCH v4 0/4] " Simon Horman
2018-05-21 14:34   ` Ulf Hansson

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=20180418095700.29948-3-horms+renesas@verge.net.au \
    --to=horms+renesas@verge.net.au \
    --cc=linux-mmc@vger.kernel.org \
    --cc=linux-renesas-soc@vger.kernel.org \
    --cc=magnus.damm@gmail.com \
    --cc=ulf.hansson@linaro.org \
    --cc=wsa+renesas@sang-engineering.com \
    /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.