From: Simon Horman <horms@verge.net.au>
To: Ulf Hansson <ulf.hansson@linaro.org>
Cc: Wolfram Sang <wsa+renesas@sang-engineering.com>,
Magnus Damm <magnus.damm@gmail.com>,
linux-mmc <linux-mmc@vger.kernel.org>,
Linux-Renesas <linux-renesas-soc@vger.kernel.org>
Subject: Re: [PATCH v4 2/4] mmc: tmio: Add tuning support
Date: Mon, 29 Aug 2016 14:05:33 +0200 [thread overview]
Message-ID: <20160829120533.GA8647@verge.net.au> (raw)
In-Reply-To: <CAPDyKFpu85h3w2JkCjyQ15P8eWfkAkYcpxR4A6bD0EpQLw9rew@mail.gmail.com>
On Fri, Aug 26, 2016 at 10:01:35AM +0200, Ulf Hansson wrote:
> On 25 August 2016 at 14:04, Simon Horman <horms@verge.net.au> wrote:
> > On Tue, Aug 23, 2016 at 05:02:56PM +0200, Ulf Hansson wrote:
...
> >> >> I am wondering whether it would it be possible to keep a cache of the
> >> >> currently used tuning values and then restore these values at
> >> >> runtime_resume?
> >> >>
> >> >> In that way you wouldn't need to force new re-tuning cycle here.
> >> >
> >> > I will check with the hardware people to see if it is practical from
> >> > that POV.
> >>
> >> Okay!
> >
> > The feedback I received is something like this:
> >
> > * The tap values calculated during retuning depend on the temperature of
> > the SoC and card.
> > * So after resume the values may be invalid.
>
> They values may also become invalid during long continues transfers,
> which prevents the ->runtime_suspend() callback to be invoked -
> because the temperature may increase.
>
> > * It may be possible to re-use the TAP values and re-tune if a transfer
> > fails but the people I spoke with were unsure of the merit of that
> > approach
>
> There's is a huge benefit!
>
> You will get a significant decreased latency at ->runtime_resume() as
> you don't need to run a complete re-tuning cycle.
>
> I can't really give you fresh numbers as it's a long time I tried this
> myself, although if you did some measurements on this it would be
> nice! :-)
>
> >
> > Personally my feeling is that we should initiate a retune on resume for
> > now as that seems to be the safest option.
>
> I don't agree. :-) I think it's better to postpone re-tune until it's
> actually needed.
>
> Re-tune happens in the request error handling path, but also if you
> configure a re-tuning period. That ought to be sufficient, don't you
> think?
Hi Ulf,
Is something like this close to what you have in mind?
diff --git a/drivers/mmc/host/sh_mobile_sdhi.c b/drivers/mmc/host/sh_mobile_sdhi.c
index 94e79449c533..fc43cf5ce958 100644
--- a/drivers/mmc/host/sh_mobile_sdhi.c
+++ b/drivers/mmc/host/sh_mobile_sdhi.c
@@ -357,11 +357,9 @@ static void sh_mobile_sdhi_prepare_tuning(struct tmio_mmc_host *host,
#define SH_MOBILE_SDHI_MAX_TAP 3
-static int sh_mobile_sdhi_select_tuning(struct tmio_mmc_host *host,
- bool *tap, int tap_size)
+static int sh_mobile_sdhi_select_tuning(struct tmio_mmc_host *host)
{
struct sh_mobile_sdhi *priv = host_to_priv(host);
- unsigned long tap_num; /* total number of taps */
unsigned long tap_cnt; /* counter of tuning success */
unsigned long tap_set; /* tap position */
unsigned long tap_start;/* start position of tuning success */
@@ -372,14 +370,6 @@ static int sh_mobile_sdhi_select_tuning(struct tmio_mmc_host *host,
/* Clear SCC_RVSREQ */
sd_scc_write32(host, priv, SH_MOBILE_SDHI_SCC_RVSREQ, 0);
- /* Select SCC */
- tap_num = (sd_scc_read32(host, priv, SH_MOBILE_SDHI_SCC_DTCNTL) >>
- SH_MOBILE_SDHI_SCC_DTCNTL_TAPNUM_SHIFT) &
- SH_MOBILE_SDHI_SCC_DTCNTL_TAPNUM_MASK;
-
- if (tap_num * 2 != tap_size)
- return -EINVAL;
-
/*
* Find the longest consecutive run of successful probes. If that
* is more than SH_MOBILE_SDHI_MAX_TAP probes long then use the
@@ -389,8 +379,8 @@ static int sh_mobile_sdhi_select_tuning(struct tmio_mmc_host *host,
ntap = 0;
tap_start = 0;
tap_end = 0;
- for (i = 0; i < tap_num * 2; i++) {
- if (tap[i] == 0)
+ for (i = 0; i < host->tap_num * 2; i++) {
+ if (test_bit(i, host->taps))
ntap++;
else {
if (ntap > tap_cnt) {
@@ -409,7 +399,7 @@ static int sh_mobile_sdhi_select_tuning(struct tmio_mmc_host *host,
}
if (tap_cnt >= SH_MOBILE_SDHI_MAX_TAP)
- tap_set = (tap_start + tap_end) / 2 % tap_num;
+ tap_set = (tap_start + tap_end) / 2 % host->tap_num;
else
return -EIO;
diff --git a/drivers/mmc/host/tmio_mmc.h b/drivers/mmc/host/tmio_mmc.h
index c932fe876690..4186045cce0d 100644
--- a/drivers/mmc/host/tmio_mmc.h
+++ b/drivers/mmc/host/tmio_mmc.h
@@ -171,8 +171,12 @@ struct tmio_mmc_host {
/* Mandatory callback for tuning to occur which is
* optional for SDR50 and mandatory for SDR104 */
unsigned int (*init_tuning)(struct tmio_mmc_host *host);
- int (*select_tuning)(struct tmio_mmc_host *host, bool *tap,
- int tap_size);
+ int (*select_tuning)(struct tmio_mmc_host *host);
+
+ /* Tuning values: 1 for success, 0 for failure */
+ DECLARE_BITMAP(taps, BITS_PER_BYTE * sizeof(long));
+ unsigned int tap_num;
+ bool use_saved_taps;
};
struct tmio_mmc_host *tmio_mmc_host_alloc(struct platform_device *pdev);
diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c
index ded8fa53e0a0..2b5c8b090ed3 100644
--- a/drivers/mmc/host/tmio_mmc_pio.c
+++ b/drivers/mmc/host/tmio_mmc_pio.c
@@ -773,43 +773,50 @@ static void tmio_mmc_hw_reset(struct mmc_host *mmc)
static int tmio_mmc_execute_tuning(struct mmc_host *mmc, u32 opcode)
{
struct tmio_mmc_host *host = mmc_priv(mmc);
- unsigned int num;
- int i, ret = 0;
- bool *tap;
+ int ret = 0;
- if (!host->init_tuning || !host->select_tuning)
- /* Tuning is not supported */
- goto out;
+ if (!host->tap_num) {
+ if (!host->init_tuning || !host->select_tuning)
+ /* Tuning is not supported */
+ goto out;
- num = host->init_tuning(host);
- if (!num)
- /* Tuning is not supported */
- goto out;
+ host->tap_num = host->init_tuning(host);
+ if (!host->tap_num)
+ /* Tuning is not supported */
+ goto out;
- tap = kmalloc(num * 2 * sizeof(*tap), GFP_KERNEL);
- if (!tap) {
- ret = -ENOMEM;
- goto out;
+ if (host->tap_num * 2 >= sizeof(host->taps) * BITS_PER_BYTE)
+ dev_warn_once(&host->pdev->dev,
+ "Too many taps, skipping tuning. Please consider "
+ "updating size of taps field of tmio_mmc_host\n");
+
+ host->use_saved_taps = false;
}
- /* Issue CMD19 twice for each tap */
- for (i = 0; i < 2 * num; i++) {
- if (host->prepare_tuning)
- host->prepare_tuning(host, i % num);
+ if (!host->use_saved_taps) {
+ int i;
+
+ bitmap_zero(host->taps, host->tap_num * 2);
- ret = mmc_send_tuning(mmc, opcode, NULL);
- if (ret && ret != -EILSEQ)
- goto err_free;
- tap[i] = (ret != 0);
+ /* Issue CMD19 twice for each tap */
+ for (i = 0; i < 2 * host->tap_num; i++) {
+ if (host->prepare_tuning)
+ host->prepare_tuning(host, i % host->tap_num);
- mdelay(1);
+ ret = mmc_send_tuning(mmc, opcode, NULL);
+ if (ret && ret != -EILSEQ)
+ goto out;
+ if (ret == 0)
+ set_bit(i, host->taps);
+
+ mdelay(1);
+ }
}
- ret = host->select_tuning(host, tap, num * 2);
+ ret = host->select_tuning(host);
-err_free:
- kfree(tap);
out:
+ host->use_saved_taps = false;
if (ret < 0) {
dev_warn(&host->pdev->dev, "Tuning procedure failed\n");
mmc_hw_reset(mmc);
@@ -1271,6 +1278,7 @@ int tmio_mmc_host_runtime_suspend(struct device *dev)
mmc_retune_timer_stop(host->mmc);
mmc_retune_needed(host->mmc);
+ host->use_saved_taps = true;
tmio_mmc_disable_mmc_irqs(host, TMIO_MASK_ALL);
next prev parent reply other threads:[~2016-08-29 12:05 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-07-27 4:13 [PATCH v4 0/4] UHS-I SDR-104 support for sh_mobile_sdhi Simon Horman
2016-07-27 4:13 ` [PATCH v4 1/4] mmc: tmio: enhance illegal sequence handling Simon Horman
2016-07-27 4:13 ` [PATCH v4 2/4] mmc: tmio: Add tuning support Simon Horman
2016-08-10 13:10 ` Wolfram Sang
2016-08-22 13:39 ` Ulf Hansson
2016-08-23 13:52 ` Simon Horman
2016-08-23 15:02 ` Ulf Hansson
2016-08-25 12:04 ` Simon Horman
2016-08-26 8:01 ` Ulf Hansson
2016-08-29 12:05 ` Simon Horman [this message]
2016-08-29 14:05 ` Ulf Hansson
2016-08-30 20:51 ` Simon Horman
2016-08-31 7:38 ` Ulf Hansson
2016-09-01 6:46 ` Simon Horman
2016-09-01 8:37 ` Simon Horman
2016-09-01 9:55 ` Ulf Hansson
2016-09-01 14:19 ` Simon Horman
2016-07-27 4:13 ` [PATCH v4 3/4] mmc: sh_mobile_sdhi: " Simon Horman
2016-07-28 0:12 ` Simon Horman
2016-07-27 4:13 ` [PATCH v4 4/4] ARM: dts: r8a7790: lager: Enable UHS-I SDR-104 Simon Horman
2016-08-10 13:12 ` [PATCH v4 0/4] UHS-I SDR-104 support for sh_mobile_sdhi Wolfram Sang
2016-08-11 8:43 ` Simon Horman
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=20160829120533.GA8647@verge.net.au \
--to=horms@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.