2018-08-20 09:25:04

by Aapo Vienamo

[permalink] [raw]
Subject: [PATCH 0/2] Tegra SDHCI rerun pad calibration periodically

Hi all,

This series implements pad drive strength recalibration. The calibration
is rerun to compensate possible changes in temperature. The calibration
procedure is rerun as part of mmc_host_ops.request before
sdhci_request() is run. The calibration is executed only if the 100 ms
recalibration interval has passed.

This series depends on the "Tegra SDHCI add support for HS200 and UHS
signaling" series.

Aapo Vienamo (2):
mmc: sdhci: Export sdhci_request()
mmc: tegra: Implement periodic pad calibration

drivers/mmc/host/sdhci-tegra.c | 22 ++++++++++++++++++++++
drivers/mmc/host/sdhci.c | 3 ++-
drivers/mmc/host/sdhci.h | 1 +
3 files changed, 25 insertions(+), 1 deletion(-)

--
2.7.4



2018-08-20 09:25:05

by Aapo Vienamo

[permalink] [raw]
Subject: [PATCH 1/2] mmc: sdhci: Export sdhci_request()

Allow SDHCI drivers to hook code before and after sdhci_request() by
making it externally visible.

Signed-off-by: Aapo Vienamo <[email protected]>
---
drivers/mmc/host/sdhci.c | 3 ++-
drivers/mmc/host/sdhci.h | 1 +
2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index da47f7b..1e0c0a6 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -1636,7 +1636,7 @@ EXPORT_SYMBOL_GPL(sdhci_set_power);
* *
\*****************************************************************************/

-static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq)
+void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq)
{
struct sdhci_host *host;
int present;
@@ -1675,6 +1675,7 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq)
mmiowb();
spin_unlock_irqrestore(&host->lock, flags);
}
+EXPORT_SYMBOL_GPL(sdhci_request);

void sdhci_set_bus_width(struct sdhci_host *host, int width)
{
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index cc963a5..73c4744 100644
--- a/drivers/mmc/host/sdhci.h
+++ b/drivers/mmc/host/sdhci.h
@@ -729,6 +729,7 @@ void sdhci_set_power(struct sdhci_host *host, unsigned char mode,
unsigned short vdd);
void sdhci_set_power_noreg(struct sdhci_host *host, unsigned char mode,
unsigned short vdd);
+void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq);
void sdhci_set_bus_width(struct sdhci_host *host, int width);
void sdhci_reset(struct sdhci_host *host, u8 mask);
void sdhci_set_uhs_signaling(struct sdhci_host *host, unsigned timing);
--
2.7.4


2018-08-20 09:25:07

by Aapo Vienamo

[permalink] [raw]
Subject: [PATCH 2/2] mmc: tegra: Implement periodic pad calibration

Rerun the pad calibration procedure before sdhci_request() if
the 100 ms recalibration interval has been exceeded.

Signed-off-by: Aapo Vienamo <[email protected]>
---
drivers/mmc/host/sdhci-tegra.c | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)

diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c
index 94624ec..ef18a0c 100644
--- a/drivers/mmc/host/sdhci-tegra.c
+++ b/drivers/mmc/host/sdhci-tegra.c
@@ -30,6 +30,7 @@
#include <linux/mmc/mmc.h>
#include <linux/mmc/slot-gpio.h>
#include <linux/gpio/consumer.h>
+#include <linux/ktime.h>

#include "sdhci-pltfm.h"

@@ -122,6 +123,7 @@ struct sdhci_tegra {
struct pinctrl_state *pinctrl_state_1v8;

struct sdhci_tegra_autocal_offsets autocal_offsets;
+ ktime_t last_calib;

u32 default_tap;
u32 default_trim;
@@ -533,6 +535,22 @@ static void tegra_sdhci_parse_pad_autocal_dt(struct sdhci_host *host)
autocal->pull_down_hs400 = autocal->pull_down_1v8;
}

+static void tegra_sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq)
+{
+ struct sdhci_host *host = mmc_priv(mmc);
+ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+ struct sdhci_tegra *tegra_host = sdhci_pltfm_priv(pltfm_host);
+ ktime_t since_calib = ktime_sub(ktime_get(), tegra_host->last_calib);
+
+ /* 100 ms calibration interval is specified in the TRM */
+ if (ktime_to_ms(since_calib) > 100) {
+ tegra_sdhci_pad_autocalib(host);
+ tegra_host->last_calib = ktime_get();
+ }
+
+ sdhci_request(mmc, mrq);
+}
+
static void tegra_sdhci_parse_tap_and_trim(struct sdhci_host *host)
{
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
@@ -1014,6 +1032,10 @@ static int sdhci_tegra_probe(struct platform_device *pdev)
sdhci_tegra_start_signal_voltage_switch;
}

+ /* Hook to periodically rerun pad calibration */
+ if (soc_data->nvquirks & NVQUIRK_HAS_PADCALIB)
+ host->mmc_host_ops.request = tegra_sdhci_request;
+
host->mmc_host_ops.hs400_enhanced_strobe =
tegra_sdhci_hs400_enhanced_strobe;

--
2.7.4


2018-08-22 10:58:48

by Adrian Hunter

[permalink] [raw]
Subject: Re: [PATCH 1/2] mmc: sdhci: Export sdhci_request()

On 20/08/18 12:23, Aapo Vienamo wrote:
> Allow SDHCI drivers to hook code before and after sdhci_request() by
> making it externally visible.
>
> Signed-off-by: Aapo Vienamo <[email protected]>

Acked-by: Adrian Hunter <[email protected]>

> ---
> drivers/mmc/host/sdhci.c | 3 ++-
> drivers/mmc/host/sdhci.h | 1 +
> 2 files changed, 3 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
> index da47f7b..1e0c0a6 100644
> --- a/drivers/mmc/host/sdhci.c
> +++ b/drivers/mmc/host/sdhci.c
> @@ -1636,7 +1636,7 @@ EXPORT_SYMBOL_GPL(sdhci_set_power);
> * *
> \*****************************************************************************/
>
> -static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq)
> +void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq)
> {
> struct sdhci_host *host;
> int present;
> @@ -1675,6 +1675,7 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq)
> mmiowb();
> spin_unlock_irqrestore(&host->lock, flags);
> }
> +EXPORT_SYMBOL_GPL(sdhci_request);
>
> void sdhci_set_bus_width(struct sdhci_host *host, int width)
> {
> diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
> index cc963a5..73c4744 100644
> --- a/drivers/mmc/host/sdhci.h
> +++ b/drivers/mmc/host/sdhci.h
> @@ -729,6 +729,7 @@ void sdhci_set_power(struct sdhci_host *host, unsigned char mode,
> unsigned short vdd);
> void sdhci_set_power_noreg(struct sdhci_host *host, unsigned char mode,
> unsigned short vdd);
> +void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq);
> void sdhci_set_bus_width(struct sdhci_host *host, int width);
> void sdhci_reset(struct sdhci_host *host, u8 mask);
> void sdhci_set_uhs_signaling(struct sdhci_host *host, unsigned timing);
>


2018-08-22 11:00:20

by Adrian Hunter

[permalink] [raw]
Subject: Re: [PATCH 2/2] mmc: tegra: Implement periodic pad calibration

On 20/08/18 12:23, Aapo Vienamo wrote:
> Rerun the pad calibration procedure before sdhci_request() if
> the 100 ms recalibration interval has been exceeded.
>
> Signed-off-by: Aapo Vienamo <[email protected]>

Acked-by: Adrian Hunter <[email protected]>

> ---
> drivers/mmc/host/sdhci-tegra.c | 22 ++++++++++++++++++++++
> 1 file changed, 22 insertions(+)
>
> diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c
> index 94624ec..ef18a0c 100644
> --- a/drivers/mmc/host/sdhci-tegra.c
> +++ b/drivers/mmc/host/sdhci-tegra.c
> @@ -30,6 +30,7 @@
> #include <linux/mmc/mmc.h>
> #include <linux/mmc/slot-gpio.h>
> #include <linux/gpio/consumer.h>
> +#include <linux/ktime.h>
>
> #include "sdhci-pltfm.h"
>
> @@ -122,6 +123,7 @@ struct sdhci_tegra {
> struct pinctrl_state *pinctrl_state_1v8;
>
> struct sdhci_tegra_autocal_offsets autocal_offsets;
> + ktime_t last_calib;
>
> u32 default_tap;
> u32 default_trim;
> @@ -533,6 +535,22 @@ static void tegra_sdhci_parse_pad_autocal_dt(struct sdhci_host *host)
> autocal->pull_down_hs400 = autocal->pull_down_1v8;
> }
>
> +static void tegra_sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq)
> +{
> + struct sdhci_host *host = mmc_priv(mmc);
> + struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
> + struct sdhci_tegra *tegra_host = sdhci_pltfm_priv(pltfm_host);
> + ktime_t since_calib = ktime_sub(ktime_get(), tegra_host->last_calib);
> +
> + /* 100 ms calibration interval is specified in the TRM */
> + if (ktime_to_ms(since_calib) > 100) {
> + tegra_sdhci_pad_autocalib(host);
> + tegra_host->last_calib = ktime_get();
> + }
> +
> + sdhci_request(mmc, mrq);
> +}
> +
> static void tegra_sdhci_parse_tap_and_trim(struct sdhci_host *host)
> {
> struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
> @@ -1014,6 +1032,10 @@ static int sdhci_tegra_probe(struct platform_device *pdev)
> sdhci_tegra_start_signal_voltage_switch;
> }
>
> + /* Hook to periodically rerun pad calibration */
> + if (soc_data->nvquirks & NVQUIRK_HAS_PADCALIB)
> + host->mmc_host_ops.request = tegra_sdhci_request;
> +
> host->mmc_host_ops.hs400_enhanced_strobe =
> tegra_sdhci_hs400_enhanced_strobe;
>
>


2018-08-23 08:52:49

by Thierry Reding

[permalink] [raw]
Subject: Re: [PATCH 0/2] Tegra SDHCI rerun pad calibration periodically

On Mon, Aug 20, 2018 at 12:23:31PM +0300, Aapo Vienamo wrote:
> Hi all,
>
> This series implements pad drive strength recalibration. The calibration
> is rerun to compensate possible changes in temperature. The calibration
> procedure is rerun as part of mmc_host_ops.request before
> sdhci_request() is run. The calibration is executed only if the 100 ms
> recalibration interval has passed.
>
> This series depends on the "Tegra SDHCI add support for HS200 and UHS
> signaling" series.
>
> Aapo Vienamo (2):
> mmc: sdhci: Export sdhci_request()
> mmc: tegra: Implement periodic pad calibration
>
> drivers/mmc/host/sdhci-tegra.c | 22 ++++++++++++++++++++++
> drivers/mmc/host/sdhci.c | 3 ++-
> drivers/mmc/host/sdhci.h | 1 +
> 3 files changed, 25 insertions(+), 1 deletion(-)

Adrian, Ulf,

Since this depends on the earlier, fairly large series, I could throw
these on top of the branch I already have. That way you don't have to
worry about the dependency yourself. Of course it's also fine if you
want to apply this yourselves, in which case the series is:

Acked-by: Thierry Reding <[email protected]>

Thanks,
Thierry


Attachments:
(No filename) (1.16 kB)
signature.asc (849.00 B)
Download all attachments

2018-08-27 09:56:22

by Ulf Hansson

[permalink] [raw]
Subject: Re: [PATCH 0/2] Tegra SDHCI rerun pad calibration periodically

On 23 August 2018 at 10:50, Thierry Reding <[email protected]> wrote:
> On Mon, Aug 20, 2018 at 12:23:31PM +0300, Aapo Vienamo wrote:
>> Hi all,
>>
>> This series implements pad drive strength recalibration. The calibration
>> is rerun to compensate possible changes in temperature. The calibration
>> procedure is rerun as part of mmc_host_ops.request before
>> sdhci_request() is run. The calibration is executed only if the 100 ms
>> recalibration interval has passed.
>>
>> This series depends on the "Tegra SDHCI add support for HS200 and UHS
>> signaling" series.
>>
>> Aapo Vienamo (2):
>> mmc: sdhci: Export sdhci_request()
>> mmc: tegra: Implement periodic pad calibration
>>
>> drivers/mmc/host/sdhci-tegra.c | 22 ++++++++++++++++++++++
>> drivers/mmc/host/sdhci.c | 3 ++-
>> drivers/mmc/host/sdhci.h | 1 +
>> 3 files changed, 25 insertions(+), 1 deletion(-)
>
> Adrian, Ulf,
>
> Since this depends on the earlier, fairly large series, I could throw
> these on top of the branch I already have. That way you don't have to
> worry about the dependency yourself. Of course it's also fine if you
> want to apply this yourselves, in which case the series is:
>
> Acked-by: Thierry Reding <[email protected]>
>
> Thanks,
> Thierry

Feel free to put in top in your branch and send a PR. BTW, Adrian has
already acked these changes.

Kind regards
Uffe

2018-08-27 10:09:06

by Ulf Hansson

[permalink] [raw]
Subject: Re: [PATCH 1/2] mmc: sdhci: Export sdhci_request()

On 20 August 2018 at 11:23, Aapo Vienamo <[email protected]> wrote:
> Allow SDHCI drivers to hook code before and after sdhci_request() by
> making it externally visible.
>
> Signed-off-by: Aapo Vienamo <[email protected]>

This one happens to be useful for other variants but Tegras, hence I
have applied this one for next. Thanks!

Thierry, you may thus drop this one from your PR. Also, you should
probably base your pull request on top of my next branch, as I have
already started to queue up some changes for sdhci.

Kind regards
Uffe

> ---
> drivers/mmc/host/sdhci.c | 3 ++-
> drivers/mmc/host/sdhci.h | 1 +
> 2 files changed, 3 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
> index da47f7b..1e0c0a6 100644
> --- a/drivers/mmc/host/sdhci.c
> +++ b/drivers/mmc/host/sdhci.c
> @@ -1636,7 +1636,7 @@ EXPORT_SYMBOL_GPL(sdhci_set_power);
> * *
> \*****************************************************************************/
>
> -static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq)
> +void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq)
> {
> struct sdhci_host *host;
> int present;
> @@ -1675,6 +1675,7 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq)
> mmiowb();
> spin_unlock_irqrestore(&host->lock, flags);
> }
> +EXPORT_SYMBOL_GPL(sdhci_request);
>
> void sdhci_set_bus_width(struct sdhci_host *host, int width)
> {
> diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
> index cc963a5..73c4744 100644
> --- a/drivers/mmc/host/sdhci.h
> +++ b/drivers/mmc/host/sdhci.h
> @@ -729,6 +729,7 @@ void sdhci_set_power(struct sdhci_host *host, unsigned char mode,
> unsigned short vdd);
> void sdhci_set_power_noreg(struct sdhci_host *host, unsigned char mode,
> unsigned short vdd);
> +void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq);
> void sdhci_set_bus_width(struct sdhci_host *host, int width);
> void sdhci_reset(struct sdhci_host *host, u8 mask);
> void sdhci_set_uhs_signaling(struct sdhci_host *host, unsigned timing);
> --
> 2.7.4
>

2018-08-27 10:13:21

by Thierry Reding

[permalink] [raw]
Subject: Re: [PATCH 1/2] mmc: sdhci: Export sdhci_request()

On Mon, Aug 27, 2018 at 12:07:08PM +0200, Ulf Hansson wrote:
> On 20 August 2018 at 11:23, Aapo Vienamo <[email protected]> wrote:
> > Allow SDHCI drivers to hook code before and after sdhci_request() by
> > making it externally visible.
> >
> > Signed-off-by: Aapo Vienamo <[email protected]>
>
> This one happens to be useful for other variants but Tegras, hence I
> have applied this one for next. Thanks!
>
> Thierry, you may thus drop this one from your PR. Also, you should
> probably base your pull request on top of my next branch, as I have
> already started to queue up some changes for sdhci.

Will do that, thanks.

Thierry


Attachments:
(No filename) (659.00 B)
signature.asc (849.00 B)
Download all attachments

2018-08-31 14:05:10

by Thierry Reding

[permalink] [raw]
Subject: Re: [PATCH 2/2] mmc: tegra: Implement periodic pad calibration

On Mon, Aug 20, 2018 at 12:23:33PM +0300, Aapo Vienamo wrote:
> Rerun the pad calibration procedure before sdhci_request() if
> the 100 ms recalibration interval has been exceeded.
>
> Signed-off-by: Aapo Vienamo <[email protected]>
> ---
> drivers/mmc/host/sdhci-tegra.c | 22 ++++++++++++++++++++++
> 1 file changed, 22 insertions(+)

Acked-by: Thierry Reding <[email protected]>


Attachments:
(No filename) (397.00 B)
signature.asc (849.00 B)
Download all attachments

2018-09-03 06:15:45

by Ulf Hansson

[permalink] [raw]
Subject: Re: [PATCH 2/2] mmc: tegra: Implement periodic pad calibration

On 20 August 2018 at 11:23, Aapo Vienamo <[email protected]> wrote:
> Rerun the pad calibration procedure before sdhci_request() if
> the 100 ms recalibration interval has been exceeded.
>
> Signed-off-by: Aapo Vienamo <[email protected]>

Applied for next, thanks!

Kind regards
Uffe

> ---
> drivers/mmc/host/sdhci-tegra.c | 22 ++++++++++++++++++++++
> 1 file changed, 22 insertions(+)
>
> diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c
> index 94624ec..ef18a0c 100644
> --- a/drivers/mmc/host/sdhci-tegra.c
> +++ b/drivers/mmc/host/sdhci-tegra.c
> @@ -30,6 +30,7 @@
> #include <linux/mmc/mmc.h>
> #include <linux/mmc/slot-gpio.h>
> #include <linux/gpio/consumer.h>
> +#include <linux/ktime.h>
>
> #include "sdhci-pltfm.h"
>
> @@ -122,6 +123,7 @@ struct sdhci_tegra {
> struct pinctrl_state *pinctrl_state_1v8;
>
> struct sdhci_tegra_autocal_offsets autocal_offsets;
> + ktime_t last_calib;
>
> u32 default_tap;
> u32 default_trim;
> @@ -533,6 +535,22 @@ static void tegra_sdhci_parse_pad_autocal_dt(struct sdhci_host *host)
> autocal->pull_down_hs400 = autocal->pull_down_1v8;
> }
>
> +static void tegra_sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq)
> +{
> + struct sdhci_host *host = mmc_priv(mmc);
> + struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
> + struct sdhci_tegra *tegra_host = sdhci_pltfm_priv(pltfm_host);
> + ktime_t since_calib = ktime_sub(ktime_get(), tegra_host->last_calib);
> +
> + /* 100 ms calibration interval is specified in the TRM */
> + if (ktime_to_ms(since_calib) > 100) {
> + tegra_sdhci_pad_autocalib(host);
> + tegra_host->last_calib = ktime_get();
> + }
> +
> + sdhci_request(mmc, mrq);
> +}
> +
> static void tegra_sdhci_parse_tap_and_trim(struct sdhci_host *host)
> {
> struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
> @@ -1014,6 +1032,10 @@ static int sdhci_tegra_probe(struct platform_device *pdev)
> sdhci_tegra_start_signal_voltage_switch;
> }
>
> + /* Hook to periodically rerun pad calibration */
> + if (soc_data->nvquirks & NVQUIRK_HAS_PADCALIB)
> + host->mmc_host_ops.request = tegra_sdhci_request;
> +
> host->mmc_host_ops.hs400_enhanced_strobe =
> tegra_sdhci_hs400_enhanced_strobe;
>
> --
> 2.7.4
>