From: <subhashj@codeaurora.org>
To: 'Arindam Nath' <arindam.nath@amd.com>, cjb@laptop.org
Cc: zhangfei.gao@gmail.com, prakity@marvell.com,
linux-mmc@vger.kernel.org, henry.su@amd.com, aaron.lu@amd.com,
anath.amd@gmail.com
Subject: RE: [PATCH v2 12/12] mmc: sdhci: add support for retuning mode 1
Date: Thu, 10 Mar 2011 19:27:30 +0530 [thread overview]
Message-ID: <002401cbdf2b$1b7fa8d0$527efa70$@org> (raw)
In-Reply-To: <1299238369-1768-13-git-send-email-arindam.nath@amd.com>
> -----Original Message-----
> From: Arindam Nath [mailto:anath.amd@gmail.com] On Behalf Of Arindam
> Nath
> Sent: Friday, March 04, 2011 5:03 PM
> To: cjb@laptop.org
> Cc: zhangfei.gao@gmail.com; prakity@marvell.com;
> subhashj@codeaurora.org; linux-mmc@vger.kernel.org; henry.su@amd.com;
> aaron.lu@amd.com; anath.amd@gmail.com; Arindam Nath
> Subject: [PATCH v2 12/12] mmc: sdhci: add support for retuning mode 1
>
> Host Controller v3.00 can support retuning modes 1,2 or 3 depending on
> the bits 46-47 of the Capabilities register. Also, the timer count for
> retuning is indicated by bits 40-43 of the same register. We initialize
> timer_list for retuning after successfull UHS-I initialization. Since
> retuning mode 1 sets a limit of 4MB on the maximum data length, we set
> max_blk_count appropriately. Once the tuning timer expires, we set
> SDHCI_NEEDS_RETUNING flag, and if the flag is set, we execute tuning
> procedure before sending the next command. We need to restore
> mmc_request
> structure after executing retuning procedure since host->mrq is used
> inside the procedure to send CMD19. We also disable and re-enable this
> flag during suspend and resume respectively, as per the spec v3.00.
>
> Signed-off-by: Arindam Nath <arindam.nath@amd.com>
> ---
> drivers/mmc/core/sd.c | 5 ++
> drivers/mmc/host/sdhci.c | 109
> ++++++++++++++++++++++++++++++++++++++++++++-
> drivers/mmc/host/sdhci.h | 6 ++-
> include/linux/mmc/host.h | 1 +
> include/linux/mmc/sdhci.h | 6 +++
> 5 files changed, 124 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c
> index ae7a771..1f3cf57 100644
> --- a/drivers/mmc/core/sd.c
> +++ b/drivers/mmc/core/sd.c
> @@ -641,6 +641,11 @@ static int mmc_sd_init_uhs_card(struct mmc_card
> *card)
> if (!mmc_host_is_spi(card->host) && card->host->ops-
> >execute_tuning)
> card->host->ops->execute_tuning(card->host);
>
> + /* Initialize and start re-tuning timer */
> + if (!mmc_host_is_spi(card->host) &&
> + card->host->ops->start_retuning_timer)
> + card->host->ops->start_retuning_timer(card->host);
Why you need extra mmc_ops for this? You can start the retuning timer when
first time your driver's "execute_tuning" ops gets executed.
> +
> out:
> kfree(status);
>
> diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
> index 2ffb0c4..8bf0408 100644
> --- a/drivers/mmc/host/sdhci.c
> +++ b/drivers/mmc/host/sdhci.c
> @@ -48,6 +48,8 @@ static void sdhci_finish_data(struct sdhci_host *);
>
> static void sdhci_send_command(struct sdhci_host *, struct mmc_command
> *);
> static void sdhci_finish_command(struct sdhci_host *);
> +static void sdhci_execute_tuning(struct mmc_host *mmc);
> +static void sdhci_tuning_timer(unsigned long data);
>
> static void sdhci_dumpregs(struct sdhci_host *host)
> {
> @@ -1240,8 +1242,34 @@ static void sdhci_request(struct mmc_host *mmc,
> struct mmc_request *mrq)
> if (!present || host->flags & SDHCI_DEVICE_DEAD) {
> host->mrq->cmd->error = -ENOMEDIUM;
> tasklet_schedule(&host->finish_tasklet);
> - } else
> + } else {
> + u32 present_state;
> +
> + present_state = sdhci_readl(host, SDHCI_PRESENT_STATE);
> + /*
> + * Check if the re-tuning timer has already expired and
> there
> + * is no on-going data transfer. If so, we need to execute
> + * tuning procedure before sending command.
> + */
> + if ((host->flags & SDHCI_NEEDS_RETUNING) &&
> + !(present_state & (SDHCI_DOING_WRITE |
> + SDHCI_DOING_READ))) {
> + host->flags &= ~SDHCI_NEEDS_RETUNING;
> + /* Reload the new initial value for timer */
> + if (host->tuning_mode == SDHCI_TUNING_MODE_1)
> + mod_timer(&host->tuning_timer, jiffies +
> + host->tuning_count * HZ);
> +
> + spin_unlock_irqrestore(&host->lock, flags);
> + sdhci_execute_tuning(mmc);
> + spin_lock_irqsave(&host->lock, flags);
> +
> + /* Restore original mmc_request structure */
> + host->mrq = mrq;
> + }
> +
> sdhci_send_command(host, mrq->cmd);
> + }
>
> mmiowb();
> spin_unlock_irqrestore(&host->lock, flags);
> @@ -1667,6 +1695,26 @@ static void sdhci_disable_preset_value(struct
> sdhci_host *host)
> sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2);
> }
>
> +static void sdhci_start_retuning_timer(struct mmc_host *mmc)
> +{
> + struct sdhci_host *host;
> + unsigned long flags;
> +
> + host = mmc_priv(mmc);
> +
> + spin_lock_irqsave(&host->lock, flags);
> +
> + if (host->tuning_count &&
> + (host->tuning_mode == SDHCI_TUNING_MODE_1)) {
> + mod_timer(&host->tuning_timer, jiffies + host->tuning_count
> *
> + HZ);
> + /* Tuning mode 1 limits the maximum data length to 4MB */
> + mmc->max_blk_count = (4 * 1024 * 1024) / mmc->max_blk_size;
> + }
> +
> + spin_unlock_irqrestore(&host->lock, flags);
> +}
> +
> static const struct mmc_host_ops sdhci_ops = {
> .request = sdhci_request,
> .set_ios = sdhci_set_ios,
> @@ -1676,6 +1724,7 @@ static const struct mmc_host_ops sdhci_ops = {
> .get_max_current_180 = sdhci_get_max_current_180,
> .execute_tuning = sdhci_execute_tuning,
> .enable_preset_value = sdhci_enable_preset_value,
> + .start_retuning_timer = sdhci_start_retuning_timer,
> };
>
>
> /**********************************************************************
> *******\
> @@ -1725,6 +1774,10 @@ static void sdhci_tasklet_finish(unsigned long
> param)
>
> del_timer(&host->timer);
>
> + if (host->version >= SDHCI_SPEC_300)
> + del_timer(&host->tuning_timer);
> +
> +
> mrq = host->mrq;
>
> /*
> @@ -1799,6 +1852,20 @@ static void sdhci_timeout_timer(unsigned long
> data)
> spin_unlock_irqrestore(&host->lock, flags);
> }
>
> +static void sdhci_tuning_timer(unsigned long data)
> +{
> + struct sdhci_host *host;
> + unsigned long flags;
> +
> + host = (struct sdhci_host *)data;
> +
> + spin_lock_irqsave(&host->lock, flags);
> +
> + host->flags |= SDHCI_NEEDS_RETUNING;
> +
> + spin_unlock_irqrestore(&host->lock, flags);
> +}
> +
>
> /**********************************************************************
> *******\
> *
> *
> * Interrupt handling
> *
> @@ -2057,6 +2124,15 @@ int sdhci_suspend_host(struct sdhci_host *host,
> pm_message_t state)
>
> sdhci_disable_card_detection(host);
>
> + /* Disable tuning since we are suspending */
> + if ((host->version >= SDHCI_SPEC_300) &&
> + host->tuning_count &&
> + (host->tuning_mode == SDHCI_TUNING_MODE_1)) {
> + host->flags &= ~SDHCI_NEEDS_RETUNING;
> + mod_timer(&host->tuning_timer, jiffies +
> + host->tuning_count * HZ);
> + }
> +
> ret = mmc_suspend_host(host->mmc);
> if (ret)
> return ret;
> @@ -2098,6 +2174,12 @@ int sdhci_resume_host(struct sdhci_host *host)
> ret = mmc_resume_host(host->mmc);
> sdhci_enable_card_detection(host);
>
> + /* Set the re-tuning expiration flag */
> + if ((host->version >= SDHCI_SPEC_300) &&
> + host->tuning_count &&
> + (host->tuning_mode == SDHCI_TUNING_MODE_1))
> + host->flags |= SDHCI_NEEDS_RETUNING;
> +
> return ret;
> }
>
> @@ -2353,6 +2435,21 @@ int sdhci_add_host(struct sdhci_host *host)
> if (caps[1] & SDHCI_DRIVER_TYPE_D)
> mmc->caps |= MMC_CAP_DRIVER_TYPE_D;
>
> + /* Initial value for re-tuning timer count */
> + host->tuning_count = (caps[1] & SDHCI_RETUNING_TIMER_COUNT_MASK)
> >>
> + SDHCI_RETUNING_TIMER_COUNT_SHIFT;
> +
> + /*
> + * In case Re-tuning Timer is not disabled, the actual value of
> + * re-tuning timer will be 2 ^ (n - 1).
> + */
> + if (host->tuning_count)
> + host->tuning_count = 1 << (host->tuning_count - 1);
> +
> + /* Re-tuning mode supported by the Host Controller */
> + host->tuning_mode = (caps[1] & SDHCI_RETUNING_MODE_MASK) >>
> + SDHCI_RETUNING_MODE_SHIFT;
> +
> ocr_avail = 0;
> /*
> * According to SD Host Controller spec v3.00, if the Host System
> @@ -2488,9 +2585,15 @@ int sdhci_add_host(struct sdhci_host *host)
>
> setup_timer(&host->timer, sdhci_timeout_timer, (unsigned
> long)host);
>
> - if (host->version >= SDHCI_SPEC_300)
> + if (host->version >= SDHCI_SPEC_300) {
> init_waitqueue_head(&host->buf_ready_int);
>
> + /* Initialize re-tuning timer */
> + init_timer(&host->tuning_timer);
> + host->tuning_timer.data = (unsigned long)host;
> + host->tuning_timer.function = sdhci_tuning_timer;
> + }
> +
> ret = request_irq(host->irq, sdhci_irq, IRQF_SHARED,
> mmc_hostname(mmc), host);
> if (ret)
> @@ -2584,6 +2687,8 @@ void sdhci_remove_host(struct sdhci_host *host,
> int dead)
> free_irq(host->irq, host);
>
> del_timer_sync(&host->timer);
> + if (host->version >= SDHCI_SPEC_300)
> + del_timer_sync(&host->tuning_timer);
>
> tasklet_kill(&host->card_tasklet);
> tasklet_kill(&host->finish_tasklet);
> diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
> index 37a8c32..53d5909 100644
> --- a/drivers/mmc/host/sdhci.h
> +++ b/drivers/mmc/host/sdhci.h
> @@ -190,7 +190,11 @@
> #define SDHCI_DRIVER_TYPE_A 0x00000010
> #define SDHCI_DRIVER_TYPE_C 0x00000020
> #define SDHCI_DRIVER_TYPE_D 0x00000040
> -#define SDHCI_USE_SDR50_TUNING 0x00002000
> +#define SDHCI_RETUNING_TIMER_COUNT_MASK 0x00000F00
> +#define SDHCI_RETUNING_TIMER_COUNT_SHIFT 8
> +#define SDHCI_USE_SDR50_TUNING 0x00002000
> +#define SDHCI_RETUNING_MODE_MASK 0x0000C000
> +#define SDHCI_RETUNING_MODE_SHIFT 14
> #define SDHCI_CLOCK_MUL_MASK 0x00FF0000
> #define SDHCI_CLOCK_MUL_SHIFT 16
>
> diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
> index e63e063..09f5d03 100644
> --- a/include/linux/mmc/host.h
> +++ b/include/linux/mmc/host.h
> @@ -131,6 +131,7 @@ struct mmc_host_ops {
> int (*get_max_current_180)(struct mmc_host *mmc);
> void (*execute_tuning)(struct mmc_host *host);
> void (*enable_preset_value)(struct mmc_host *host);
> + void (*start_retuning_timer)(struct mmc_host *host);
> };
>
> struct mmc_card;
> diff --git a/include/linux/mmc/sdhci.h b/include/linux/mmc/sdhci.h
> index 4be4022..c6539be 100644
> --- a/include/linux/mmc/sdhci.h
> +++ b/include/linux/mmc/sdhci.h
> @@ -110,6 +110,7 @@ struct sdhci_host {
> #define SDHCI_REQ_USE_DMA (1<<2) /* Use DMA for this req. */
> #define SDHCI_DEVICE_DEAD (1<<3) /* Device unresponsive */
> #define SDHCI_SDR50_NEEDS_TUNING (1<<4) /* SDR50 needs tuning */
> +#define SDHCI_NEEDS_RETUNING (1<<5) /* Host needs retuning */
>
> unsigned int version; /* SDHCI spec. version */
>
> @@ -152,6 +153,11 @@ struct sdhci_host {
> wait_queue_head_t buf_ready_int; /* Waitqueue for Buffer Read
> Ready interrupt */
> unsigned int tuning_done; /* Condition flag set
> when CMD19 succeeds */
>
> + unsigned int tuning_count; /* Timer count for re-
> tuning */
> + unsigned int tuning_mode; /* Re-tuning mode
> supported by host */
> +#define SDHCI_TUNING_MODE_1 0
> + struct timer_list tuning_timer; /* Timer for tuning */
> +
> unsigned long private[0] ____cacheline_aligned;
> };
> #endif /* __SDHCI_H */
> --
> 1.7.1
next prev parent reply other threads:[~2011-03-10 13:57 UTC|newest]
Thread overview: 125+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-03-04 11:32 [PATCH v2 00/12] add support for host controller v3.00 Arindam Nath
2011-03-04 11:32 ` [PATCH v2 01/12] mmc: sdhci: add support for auto CMD23 Arindam Nath
2011-03-09 12:22 ` subhashj
2011-03-09 12:55 ` Nath, Arindam
2011-03-15 11:23 ` Subhash Jadavani
2011-03-15 11:35 ` Nath, Arindam
2011-03-15 11:52 ` Subhash Jadavani
2011-03-16 6:07 ` Nath, Arindam
2011-03-04 11:32 ` [PATCH v2 02/12] mmc: sd: add support for signal voltage switch procedure Arindam Nath
2011-03-04 11:47 ` Wolfram Sang
2011-03-04 11:52 ` Nath, Arindam
2011-03-09 10:44 ` subhashj
2011-03-10 6:30 ` subhashj
2011-03-10 8:05 ` Nath, Arindam
2011-03-09 12:45 ` zhangfei gao
2011-03-10 8:11 ` Nath, Arindam
2011-03-15 10:18 ` Subhash Jadavani
2011-03-15 10:32 ` Nath, Arindam
2011-03-15 11:18 ` Subhash Jadavani
2011-03-15 11:28 ` Nath, Arindam
2011-03-15 11:58 ` Subhash Jadavani
2011-03-16 3:03 ` zhangfei gao
2011-03-16 6:30 ` Nath, Arindam
2011-03-16 10:44 ` zhangfei gao
2011-03-16 10:48 ` Nath, Arindam
2011-03-16 21:39 ` Philip Rakity
2011-03-17 4:18 ` Nath, Arindam
2011-03-24 10:52 ` zhangfei gao
2011-03-24 10:59 ` Nath, Arindam
2011-03-04 11:32 ` [PATCH v2 03/12] mmc: sd: query function modes for uhs cards Arindam Nath
2011-03-09 14:08 ` subhashj
2011-03-09 14:31 ` Nath, Arindam
2011-03-09 18:04 ` subhashj
2011-03-09 18:16 ` Nath, Arindam
2011-03-04 11:32 ` [PATCH v2 04/12] mmc: sd: add support for driver type selection Arindam Nath
2011-03-09 5:33 ` Philip Rakity
2011-03-09 8:11 ` Nath, Arindam
2011-03-10 6:57 ` subhashj
2011-03-10 8:31 ` Nath, Arindam
2011-03-10 10:28 ` subhashj
2011-03-10 10:44 ` Nath, Arindam
2011-03-10 11:25 ` subhashj
2011-03-10 11:34 ` Nath, Arindam
2011-03-04 11:32 ` [PATCH v2 05/12] mmc: sdhci: reset sdclk before setting high speed enable Arindam Nath
2011-03-05 4:57 ` Philip Rakity
2011-03-05 5:07 ` Nath, Arindam
2011-03-04 11:32 ` [PATCH v2 06/12] mmc: sd: add support for uhs bus speed mode selection Arindam Nath
2011-03-10 8:00 ` subhashj
2011-03-10 8:36 ` Nath, Arindam
2011-03-10 10:07 ` subhashj
2011-03-10 10:15 ` Nath, Arindam
2011-03-21 6:42 ` Subhash Jadavani
2011-03-23 6:04 ` Nath, Arindam
2011-03-23 6:14 ` Subhash Jadavani
2011-03-23 6:17 ` Nath, Arindam
2011-03-23 6:26 ` Subhash Jadavani
2011-03-23 6:35 ` Nath, Arindam
2011-03-23 7:23 ` Subhash Jadavani
2011-03-23 14:02 ` Nath, Arindam
2011-03-24 7:25 ` Subhash Jadavani
2011-03-24 8:42 ` Nath, Arindam
2011-03-04 11:32 ` [PATCH v2 07/12] mmc: sd: set current limit for uhs cards Arindam Nath
2011-03-09 21:41 ` Philip Rakity
2011-03-10 3:12 ` Nath, Arindam
2011-03-10 8:16 ` subhashj
2011-03-10 8:43 ` Nath, Arindam
2011-03-10 9:45 ` subhashj
2011-03-16 14:26 ` Philip Rakity
2011-03-16 14:32 ` Nath, Arindam
2011-03-16 14:51 ` Philip Rakity
2011-03-16 15:00 ` Nath, Arindam
2011-03-16 15:18 ` Philip Rakity
2011-03-16 15:24 ` Nath, Arindam
2011-03-16 15:31 ` Philip Rakity
2011-03-16 15:33 ` Nath, Arindam
2011-03-16 15:34 ` Philip Rakity
2011-03-21 7:43 ` Subhash Jadavani
2011-03-21 7:54 ` Nath, Arindam
2011-03-04 11:32 ` [PATCH v2 08/12] mmc: sd: report correct speed and capacity of " Arindam Nath
2011-03-10 11:48 ` subhashj
2011-03-10 13:28 ` Nath, Arindam
2011-03-10 13:41 ` subhashj
2011-03-04 11:32 ` [PATCH v2 09/12] mmc: sd: add support for tuning during uhs initialization Arindam Nath
2011-03-04 18:27 ` Philip Rakity
2011-03-04 18:48 ` Nath, Arindam
2011-03-04 18:34 ` Philip Rakity
2011-03-04 18:54 ` Nath, Arindam
2011-03-15 10:32 ` zhangfei gao
2011-03-15 10:43 ` Nath, Arindam
2011-03-16 2:51 ` zhangfei gao
2011-03-16 6:20 ` Nath, Arindam
2011-03-16 10:18 ` zhangfei gao
2011-03-21 9:43 ` Subhash Jadavani
2011-03-21 9:50 ` Nath, Arindam
2011-03-23 6:58 ` Subhash Jadavani
2011-03-21 10:58 ` Subhash Jadavani
2011-03-21 11:07 ` Nath, Arindam
2011-03-23 6:08 ` Subhash Jadavani
2011-03-23 6:14 ` Nath, Arindam
2011-03-23 6:19 ` Subhash Jadavani
2011-03-23 6:22 ` Nath, Arindam
2011-03-23 6:34 ` Subhash Jadavani
2011-03-23 6:41 ` Nath, Arindam
2011-03-23 6:45 ` Subhash Jadavani
2011-03-23 6:48 ` Nath, Arindam
2011-03-04 11:32 ` [PATCH v2 10/12] mmc: sdhci: enable preset value after " Arindam Nath
2011-03-10 13:23 ` subhashj
2011-03-10 13:30 ` Nath, Arindam
2011-03-10 13:45 ` subhashj
2011-03-10 13:49 ` Nath, Arindam
2011-03-10 14:03 ` subhashj
2011-03-10 14:07 ` Nath, Arindam
2011-03-10 14:12 ` subhashj
2011-03-10 14:15 ` Nath, Arindam
2011-03-10 14:19 ` subhashj
2011-03-10 14:24 ` Nath, Arindam
2011-03-04 11:32 ` [PATCH v2 11/12] mmc: sdhci: add support for programmable clock mode Arindam Nath
2011-03-04 11:32 ` [PATCH v2 12/12] mmc: sdhci: add support for retuning mode 1 Arindam Nath
2011-03-10 13:57 ` subhashj [this message]
2011-03-10 14:00 ` Nath, Arindam
2011-03-04 15:16 ` [PATCH v2 00/12] add support for host controller v3.00 Chris Ball
2011-03-04 15:55 ` Nath, Arindam
2011-03-11 13:13 ` subhashj
2011-03-11 15:29 ` Nath, Arindam
2011-03-11 16:06 ` Chris Ball
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='002401cbdf2b$1b7fa8d0$527efa70$@org' \
--to=subhashj@codeaurora.org \
--cc=aaron.lu@amd.com \
--cc=anath.amd@gmail.com \
--cc=arindam.nath@amd.com \
--cc=cjb@laptop.org \
--cc=henry.su@amd.com \
--cc=linux-mmc@vger.kernel.org \
--cc=prakity@marvell.com \
--cc=zhangfei.gao@gmail.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.