linux-tegra.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/2] mmc: tegra: properly disable card clock
@ 2016-02-29 20:56 Lucas Stach
       [not found] ` <1456779385-18996-1-git-send-email-dev-8ppwABl0HbeELgA04lAiVw@public.gmane.org>
                   ` (3 more replies)
  0 siblings, 4 replies; 10+ messages in thread
From: Lucas Stach @ 2016-02-29 20:56 UTC (permalink / raw)
  To: Ulf Hansson, Adrian Hunter
  Cc: Stephen Warren, Thierry Reding, Alexandre Courbot, Jon Hunter,
	linux-mmc, linux-tegra

The new code to do the clock rate setting externally to the SDMMC
module has a shortcut to not propagate changes with a 0 rate to
the CAR by simply bailing out. This breaks proper cutting of the
card clock. Fix it by directly calling the correct sdhci function.

Fixes: a8e326a911d3 "mmc: tegra: implement module external clock change"
Signed-off-by: Lucas Stach <dev@lynxeye.de>
---
 drivers/mmc/host/sdhci-tegra.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c
index 212d51f..46a6bd1 100644
--- a/drivers/mmc/host/sdhci-tegra.c
+++ b/drivers/mmc/host/sdhci-tegra.c
@@ -194,7 +194,7 @@ static void tegra_sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
 	unsigned long host_clk;
 
 	if (!clock)
-		return;
+		return sdhci_set_clock(host, clock);;
 
 	host_clk = tegra_host->ddr_signaling ? clock * 2 : clock;
 	clk_set_rate(pltfm_host->clk, host_clk);
-- 
2.5.0


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

* [PATCH 2/2] mmc: tegra: implement memcomp pad calibration
       [not found] ` <1456779385-18996-1-git-send-email-dev-8ppwABl0HbeELgA04lAiVw@public.gmane.org>
@ 2016-02-29 20:56   ` Lucas Stach
  2016-03-04 13:02     ` Adrian Hunter
  2016-03-16 11:37     ` Ulf Hansson
  0 siblings, 2 replies; 10+ messages in thread
From: Lucas Stach @ 2016-02-29 20:56 UTC (permalink / raw)
  To: Ulf Hansson, Adrian Hunter
  Cc: Stephen Warren, Thierry Reding, Alexandre Courbot, Jon Hunter,
	linux-mmc-u79uwXL29TY76Z2rM5mHXA,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA

The Tegra30+ SDMMC module has memcomp pads that are used to
automatically find and set the correct drive strength settings to
the sdmmc pads. The calibration needs to be manually kicked off
when the card signal voltage is changed, after the card clock is
supplied again.

Signed-off-by: Lucas Stach <dev-8ppwABl0HbeELgA04lAiVw@public.gmane.org>
---
This commit allows signal voltage changes on my Tegar30 Beaver to
succeed, making UHS-I modes work.
---
 drivers/mmc/host/sdhci-tegra.c | 47 +++++++++++++++++++++++++++++++++++++++---
 1 file changed, 44 insertions(+), 3 deletions(-)

diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c
index 46a6bd1..9971732 100644
--- a/drivers/mmc/host/sdhci-tegra.c
+++ b/drivers/mmc/host/sdhci-tegra.c
@@ -12,6 +12,7 @@
  *
  */
 
+#include "linux/delay.h"
 #include <linux/err.h>
 #include <linux/module.h>
 #include <linux/init.h>
@@ -42,12 +43,17 @@
 #define SDHCI_MISC_CTRL_ENABLE_SDHCI_SPEC_300	0x20
 #define SDHCI_MISC_CTRL_ENABLE_DDR50		0x200
 
+#define SDHCI_TEGRA_AUTO_CAL_CONFIG		0x1e4
+#define SDHCI_AUTO_CAL_START			BIT(31)
+#define SDHCI_AUTO_CAL_ENABLE			BIT(29)
+
 #define NVQUIRK_FORCE_SDHCI_SPEC_200	BIT(0)
 #define NVQUIRK_ENABLE_BLOCK_GAP_DET	BIT(1)
 #define NVQUIRK_ENABLE_SDHCI_SPEC_300	BIT(2)
 #define NVQUIRK_ENABLE_SDR50		BIT(3)
 #define NVQUIRK_ENABLE_SDR104		BIT(4)
 #define NVQUIRK_ENABLE_DDR50		BIT(5)
+#define NVQUIRK_HAS_PADCALIB		BIT(6)
 
 struct sdhci_tegra_soc_data {
 	const struct sdhci_pltfm_data *pdata;
@@ -58,6 +64,7 @@ struct sdhci_tegra {
 	const struct sdhci_tegra_soc_data *soc_data;
 	struct gpio_desc *power_gpio;
 	bool ddr_signaling;
+	bool pad_calib_required;
 };
 
 static u16 tegra_sdhci_readw(struct sdhci_host *host, int reg)
@@ -165,6 +172,9 @@ static void tegra_sdhci_reset(struct sdhci_host *host, u8 mask)
 		clk_ctrl |= SDHCI_CLOCK_CTRL_SDR50_TUNING_OVERRIDE;
 	sdhci_writel(host, clk_ctrl, SDHCI_TEGRA_VENDOR_CLOCK_CTRL);
 
+	if (soc_data->nvquirks & NVQUIRK_HAS_PADCALIB)
+		tegra_host->pad_calib_required = true;
+
 	tegra_host->ddr_signaling = false;
 }
 
@@ -187,6 +197,17 @@ static void tegra_sdhci_set_bus_width(struct sdhci_host *host, int bus_width)
 	sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
 }
 
+static void tegra_sdhci_pad_autocalib(struct sdhci_host *host)
+{
+	u32 val;
+
+	mdelay(1);
+
+	val = sdhci_readl(host, SDHCI_TEGRA_AUTO_CAL_CONFIG);
+	val |= SDHCI_AUTO_CAL_ENABLE | SDHCI_AUTO_CAL_START;
+	sdhci_writel(host,val, SDHCI_TEGRA_AUTO_CAL_CONFIG);
+}
+
 static void tegra_sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
 {
 	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
@@ -200,7 +221,12 @@ static void tegra_sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
 	clk_set_rate(pltfm_host->clk, host_clk);
 	host->max_clk = clk_get_rate(pltfm_host->clk);
 
-	return sdhci_set_clock(host, clock);
+	sdhci_set_clock(host, clock);
+
+	if (tegra_host->pad_calib_required) {
+		tegra_sdhci_pad_autocalib(host);
+		tegra_host->pad_calib_required = false;
+	}
 }
 
 static void tegra_sdhci_set_uhs_signaling(struct sdhci_host *host,
@@ -270,6 +296,16 @@ static int tegra_sdhci_execute_tuning(struct sdhci_host *host, u32 opcode)
 	return mmc_send_tuning(host->mmc, opcode, NULL);
 }
 
+static void tegra_sdhci_voltage_switch(struct sdhci_host *host)
+{
+	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+	struct sdhci_tegra *tegra_host = pltfm_host->priv;
+	const struct sdhci_tegra_soc_data *soc_data = tegra_host->soc_data;
+
+	if (soc_data->nvquirks & NVQUIRK_HAS_PADCALIB)
+		tegra_host->pad_calib_required = true;
+}
+
 static const struct sdhci_ops tegra_sdhci_ops = {
 	.get_ro     = tegra_sdhci_get_ro,
 	.read_w     = tegra_sdhci_readw,
@@ -279,6 +315,7 @@ static const struct sdhci_ops tegra_sdhci_ops = {
 	.reset      = tegra_sdhci_reset,
 	.platform_execute_tuning = tegra_sdhci_execute_tuning,
 	.set_uhs_signaling = tegra_sdhci_set_uhs_signaling,
+	.voltage_switch = tegra_sdhci_voltage_switch,
 	.get_max_clock = tegra_sdhci_get_max_clock,
 };
 
@@ -312,7 +349,8 @@ static const struct sdhci_tegra_soc_data soc_data_tegra30 = {
 	.pdata = &sdhci_tegra30_pdata,
 	.nvquirks = NVQUIRK_ENABLE_SDHCI_SPEC_300 |
 		    NVQUIRK_ENABLE_SDR50 |
-		    NVQUIRK_ENABLE_SDR104,
+		    NVQUIRK_ENABLE_SDR104 |
+		    NVQUIRK_HAS_PADCALIB,
 };
 
 static const struct sdhci_ops tegra114_sdhci_ops = {
@@ -325,6 +363,7 @@ static const struct sdhci_ops tegra114_sdhci_ops = {
 	.reset      = tegra_sdhci_reset,
 	.platform_execute_tuning = tegra_sdhci_execute_tuning,
 	.set_uhs_signaling = tegra_sdhci_set_uhs_signaling,
+	.voltage_switch = tegra_sdhci_voltage_switch,
 	.get_max_clock = tegra_sdhci_get_max_clock,
 };
 
@@ -347,7 +386,8 @@ static const struct sdhci_tegra_soc_data soc_data_tegra124 = {
 	.pdata = &sdhci_tegra114_pdata,
 	.nvquirks = NVQUIRK_ENABLE_SDR50 |
 		    NVQUIRK_ENABLE_DDR50 |
-		    NVQUIRK_ENABLE_SDR104,
+		    NVQUIRK_ENABLE_SDR104 |
+		    NVQUIRK_HAS_PADCALIB,
 };
 
 static const struct sdhci_pltfm_data sdhci_tegra210_pdata = {
@@ -402,6 +442,7 @@ static int sdhci_tegra_probe(struct platform_device *pdev)
 		goto err_alloc_tegra_host;
 	}
 	tegra_host->ddr_signaling = false;
+	tegra_host->pad_calib_required = false;
 	tegra_host->soc_data = soc_data;
 	pltfm_host->priv = tegra_host;
 
-- 
2.5.0

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

* Re: [PATCH 1/2] mmc: tegra: properly disable card clock
  2016-02-29 20:56 [PATCH 1/2] mmc: tegra: properly disable card clock Lucas Stach
       [not found] ` <1456779385-18996-1-git-send-email-dev-8ppwABl0HbeELgA04lAiVw@public.gmane.org>
@ 2016-03-03 14:06 ` Adrian Hunter
  2016-03-04  9:41 ` Ulf Hansson
  2016-03-17 11:29 ` Jon Hunter
  3 siblings, 0 replies; 10+ messages in thread
From: Adrian Hunter @ 2016-03-03 14:06 UTC (permalink / raw)
  To: Lucas Stach, Ulf Hansson
  Cc: Stephen Warren, Thierry Reding, Alexandre Courbot, Jon Hunter,
	linux-mmc, linux-tegra

On 29/02/16 22:56, Lucas Stach wrote:
> The new code to do the clock rate setting externally to the SDMMC
> module has a shortcut to not propagate changes with a 0 rate to
> the CAR by simply bailing out. This breaks proper cutting of the
> card clock. Fix it by directly calling the correct sdhci function.
> 
> Fixes: a8e326a911d3 "mmc: tegra: implement module external clock change"
> Signed-off-by: Lucas Stach <dev@lynxeye.de>
> ---
>  drivers/mmc/host/sdhci-tegra.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c
> index 212d51f..46a6bd1 100644
> --- a/drivers/mmc/host/sdhci-tegra.c
> +++ b/drivers/mmc/host/sdhci-tegra.c
> @@ -194,7 +194,7 @@ static void tegra_sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
>  	unsigned long host_clk;
>  
>  	if (!clock)
> -		return;
> +		return sdhci_set_clock(host, clock);;
>  
>  	host_clk = tegra_host->ddr_signaling ? clock * 2 : clock;
>  	clk_set_rate(pltfm_host->clk, host_clk);
> 

Acked-by: Adrian Hunter <adrian.hunter@intel.com>


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

* Re: [PATCH 1/2] mmc: tegra: properly disable card clock
  2016-02-29 20:56 [PATCH 1/2] mmc: tegra: properly disable card clock Lucas Stach
       [not found] ` <1456779385-18996-1-git-send-email-dev-8ppwABl0HbeELgA04lAiVw@public.gmane.org>
  2016-03-03 14:06 ` [PATCH 1/2] mmc: tegra: properly disable card clock Adrian Hunter
@ 2016-03-04  9:41 ` Ulf Hansson
       [not found]   ` <CAPDyKFoJfNE7HcL3BcbRQpw6uOvQYrD=bEYvgUxjvOaX36o=fA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
  2016-03-17 11:29 ` Jon Hunter
  3 siblings, 1 reply; 10+ messages in thread
From: Ulf Hansson @ 2016-03-04  9:41 UTC (permalink / raw)
  To: Lucas Stach
  Cc: Adrian Hunter, Stephen Warren, Thierry Reding, Alexandre Courbot,
	Jon Hunter, linux-mmc, linux-tegra@vger.kernel.org

On 29 February 2016 at 21:56, Lucas Stach <dev@lynxeye.de> wrote:
> The new code to do the clock rate setting externally to the SDMMC
> module has a shortcut to not propagate changes with a 0 rate to
> the CAR by simply bailing out. This breaks proper cutting of the
> card clock. Fix it by directly calling the correct sdhci function.
>
> Fixes: a8e326a911d3 "mmc: tegra: implement module external clock change"
> Signed-off-by: Lucas Stach <dev@lynxeye.de>

Thanks, applied for fixes!

Kind regards
Uffe

> ---
>  drivers/mmc/host/sdhci-tegra.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c
> index 212d51f..46a6bd1 100644
> --- a/drivers/mmc/host/sdhci-tegra.c
> +++ b/drivers/mmc/host/sdhci-tegra.c
> @@ -194,7 +194,7 @@ static void tegra_sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
>         unsigned long host_clk;
>
>         if (!clock)
> -               return;
> +               return sdhci_set_clock(host, clock);;
>
>         host_clk = tegra_host->ddr_signaling ? clock * 2 : clock;
>         clk_set_rate(pltfm_host->clk, host_clk);
> --
> 2.5.0
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* Re: [PATCH 2/2] mmc: tegra: implement memcomp pad calibration
  2016-02-29 20:56   ` [PATCH 2/2] mmc: tegra: implement memcomp pad calibration Lucas Stach
@ 2016-03-04 13:02     ` Adrian Hunter
  2016-03-16 11:37     ` Ulf Hansson
  1 sibling, 0 replies; 10+ messages in thread
From: Adrian Hunter @ 2016-03-04 13:02 UTC (permalink / raw)
  To: Lucas Stach, Ulf Hansson
  Cc: Stephen Warren, Thierry Reding, Alexandre Courbot, Jon Hunter,
	linux-mmc, linux-tegra

On 29/02/16 22:56, Lucas Stach wrote:
> The Tegra30+ SDMMC module has memcomp pads that are used to
> automatically find and set the correct drive strength settings to
> the sdmmc pads. The calibration needs to be manually kicked off
> when the card signal voltage is changed, after the card clock is
> supplied again.
> 
> Signed-off-by: Lucas Stach <dev@lynxeye.de>
> ---
> This commit allows signal voltage changes on my Tegar30 Beaver to
> succeed, making UHS-I modes work.
> ---

Doesn't apply cleanly, but otherwise looks OK.

Acked-by: Adrian Hunter <adrian.hunter@intel.com>


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

* Re: [PATCH 2/2] mmc: tegra: implement memcomp pad calibration
  2016-02-29 20:56   ` [PATCH 2/2] mmc: tegra: implement memcomp pad calibration Lucas Stach
  2016-03-04 13:02     ` Adrian Hunter
@ 2016-03-16 11:37     ` Ulf Hansson
  2016-03-16 15:04       ` Ulf Hansson
  1 sibling, 1 reply; 10+ messages in thread
From: Ulf Hansson @ 2016-03-16 11:37 UTC (permalink / raw)
  To: Lucas Stach
  Cc: Adrian Hunter, Stephen Warren, Thierry Reding, Alexandre Courbot,
	Jon Hunter, linux-mmc, linux-tegra@vger.kernel.org

On 29 February 2016 at 21:56, Lucas Stach <dev@lynxeye.de> wrote:
> The Tegra30+ SDMMC module has memcomp pads that are used to
> automatically find and set the correct drive strength settings to
> the sdmmc pads. The calibration needs to be manually kicked off
> when the card signal voltage is changed, after the card clock is
> supplied again.
>
> Signed-off-by: Lucas Stach <dev@lynxeye.de>

Thanks applied for next, with a minor trivial fixup to resolve the
conflict when applying.

Kind regards
Uffe

> ---
> This commit allows signal voltage changes on my Tegar30 Beaver to
> succeed, making UHS-I modes work.
> ---
>  drivers/mmc/host/sdhci-tegra.c | 47 +++++++++++++++++++++++++++++++++++++++---
>  1 file changed, 44 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c
> index 46a6bd1..9971732 100644
> --- a/drivers/mmc/host/sdhci-tegra.c
> +++ b/drivers/mmc/host/sdhci-tegra.c
> @@ -12,6 +12,7 @@
>   *
>   */
>
> +#include "linux/delay.h"
>  #include <linux/err.h>
>  #include <linux/module.h>
>  #include <linux/init.h>
> @@ -42,12 +43,17 @@
>  #define SDHCI_MISC_CTRL_ENABLE_SDHCI_SPEC_300  0x20
>  #define SDHCI_MISC_CTRL_ENABLE_DDR50           0x200
>
> +#define SDHCI_TEGRA_AUTO_CAL_CONFIG            0x1e4
> +#define SDHCI_AUTO_CAL_START                   BIT(31)
> +#define SDHCI_AUTO_CAL_ENABLE                  BIT(29)
> +
>  #define NVQUIRK_FORCE_SDHCI_SPEC_200   BIT(0)
>  #define NVQUIRK_ENABLE_BLOCK_GAP_DET   BIT(1)
>  #define NVQUIRK_ENABLE_SDHCI_SPEC_300  BIT(2)
>  #define NVQUIRK_ENABLE_SDR50           BIT(3)
>  #define NVQUIRK_ENABLE_SDR104          BIT(4)
>  #define NVQUIRK_ENABLE_DDR50           BIT(5)
> +#define NVQUIRK_HAS_PADCALIB           BIT(6)
>
>  struct sdhci_tegra_soc_data {
>         const struct sdhci_pltfm_data *pdata;
> @@ -58,6 +64,7 @@ struct sdhci_tegra {
>         const struct sdhci_tegra_soc_data *soc_data;
>         struct gpio_desc *power_gpio;
>         bool ddr_signaling;
> +       bool pad_calib_required;
>  };
>
>  static u16 tegra_sdhci_readw(struct sdhci_host *host, int reg)
> @@ -165,6 +172,9 @@ static void tegra_sdhci_reset(struct sdhci_host *host, u8 mask)
>                 clk_ctrl |= SDHCI_CLOCK_CTRL_SDR50_TUNING_OVERRIDE;
>         sdhci_writel(host, clk_ctrl, SDHCI_TEGRA_VENDOR_CLOCK_CTRL);
>
> +       if (soc_data->nvquirks & NVQUIRK_HAS_PADCALIB)
> +               tegra_host->pad_calib_required = true;
> +
>         tegra_host->ddr_signaling = false;
>  }
>
> @@ -187,6 +197,17 @@ static void tegra_sdhci_set_bus_width(struct sdhci_host *host, int bus_width)
>         sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
>  }
>
> +static void tegra_sdhci_pad_autocalib(struct sdhci_host *host)
> +{
> +       u32 val;
> +
> +       mdelay(1);
> +
> +       val = sdhci_readl(host, SDHCI_TEGRA_AUTO_CAL_CONFIG);
> +       val |= SDHCI_AUTO_CAL_ENABLE | SDHCI_AUTO_CAL_START;
> +       sdhci_writel(host,val, SDHCI_TEGRA_AUTO_CAL_CONFIG);
> +}
> +
>  static void tegra_sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
>  {
>         struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
> @@ -200,7 +221,12 @@ static void tegra_sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
>         clk_set_rate(pltfm_host->clk, host_clk);
>         host->max_clk = clk_get_rate(pltfm_host->clk);
>
> -       return sdhci_set_clock(host, clock);
> +       sdhci_set_clock(host, clock);
> +
> +       if (tegra_host->pad_calib_required) {
> +               tegra_sdhci_pad_autocalib(host);
> +               tegra_host->pad_calib_required = false;
> +       }
>  }
>
>  static void tegra_sdhci_set_uhs_signaling(struct sdhci_host *host,
> @@ -270,6 +296,16 @@ static int tegra_sdhci_execute_tuning(struct sdhci_host *host, u32 opcode)
>         return mmc_send_tuning(host->mmc, opcode, NULL);
>  }
>
> +static void tegra_sdhci_voltage_switch(struct sdhci_host *host)
> +{
> +       struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
> +       struct sdhci_tegra *tegra_host = pltfm_host->priv;
> +       const struct sdhci_tegra_soc_data *soc_data = tegra_host->soc_data;
> +
> +       if (soc_data->nvquirks & NVQUIRK_HAS_PADCALIB)
> +               tegra_host->pad_calib_required = true;
> +}
> +
>  static const struct sdhci_ops tegra_sdhci_ops = {
>         .get_ro     = tegra_sdhci_get_ro,
>         .read_w     = tegra_sdhci_readw,
> @@ -279,6 +315,7 @@ static const struct sdhci_ops tegra_sdhci_ops = {
>         .reset      = tegra_sdhci_reset,
>         .platform_execute_tuning = tegra_sdhci_execute_tuning,
>         .set_uhs_signaling = tegra_sdhci_set_uhs_signaling,
> +       .voltage_switch = tegra_sdhci_voltage_switch,
>         .get_max_clock = tegra_sdhci_get_max_clock,
>  };
>
> @@ -312,7 +349,8 @@ static const struct sdhci_tegra_soc_data soc_data_tegra30 = {
>         .pdata = &sdhci_tegra30_pdata,
>         .nvquirks = NVQUIRK_ENABLE_SDHCI_SPEC_300 |
>                     NVQUIRK_ENABLE_SDR50 |
> -                   NVQUIRK_ENABLE_SDR104,
> +                   NVQUIRK_ENABLE_SDR104 |
> +                   NVQUIRK_HAS_PADCALIB,
>  };
>
>  static const struct sdhci_ops tegra114_sdhci_ops = {
> @@ -325,6 +363,7 @@ static const struct sdhci_ops tegra114_sdhci_ops = {
>         .reset      = tegra_sdhci_reset,
>         .platform_execute_tuning = tegra_sdhci_execute_tuning,
>         .set_uhs_signaling = tegra_sdhci_set_uhs_signaling,
> +       .voltage_switch = tegra_sdhci_voltage_switch,
>         .get_max_clock = tegra_sdhci_get_max_clock,
>  };
>
> @@ -347,7 +386,8 @@ static const struct sdhci_tegra_soc_data soc_data_tegra124 = {
>         .pdata = &sdhci_tegra114_pdata,
>         .nvquirks = NVQUIRK_ENABLE_SDR50 |
>                     NVQUIRK_ENABLE_DDR50 |
> -                   NVQUIRK_ENABLE_SDR104,
> +                   NVQUIRK_ENABLE_SDR104 |
> +                   NVQUIRK_HAS_PADCALIB,
>  };
>
>  static const struct sdhci_pltfm_data sdhci_tegra210_pdata = {
> @@ -402,6 +442,7 @@ static int sdhci_tegra_probe(struct platform_device *pdev)
>                 goto err_alloc_tegra_host;
>         }
>         tegra_host->ddr_signaling = false;
> +       tegra_host->pad_calib_required = false;
>         tegra_host->soc_data = soc_data;
>         pltfm_host->priv = tegra_host;
>
> --
> 2.5.0
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* Re: [PATCH 1/2] mmc: tegra: properly disable card clock
       [not found]   ` <CAPDyKFoJfNE7HcL3BcbRQpw6uOvQYrD=bEYvgUxjvOaX36o=fA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
@ 2016-03-16 12:35     ` Ulf Hansson
  0 siblings, 0 replies; 10+ messages in thread
From: Ulf Hansson @ 2016-03-16 12:35 UTC (permalink / raw)
  To: Lucas Stach
  Cc: Adrian Hunter, Stephen Warren, Thierry Reding, Alexandre Courbot,
	Jon Hunter, linux-mmc,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org

On 4 March 2016 at 10:41, Ulf Hansson <ulf.hansson-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org> wrote:
> On 29 February 2016 at 21:56, Lucas Stach <dev-8ppwABl0HbeELgA04lAiVw@public.gmane.org> wrote:
>> The new code to do the clock rate setting externally to the SDMMC
>> module has a shortcut to not propagate changes with a 0 rate to
>> the CAR by simply bailing out. This breaks proper cutting of the
>> card clock. Fix it by directly calling the correct sdhci function.
>>
>> Fixes: a8e326a911d3 "mmc: tegra: implement module external clock change"
>> Signed-off-by: Lucas Stach <dev-8ppwABl0HbeELgA04lAiVw@public.gmane.org>
>
> Thanks, applied for fixes!
>

Unfortunate I failed to send this in a PR to Linus within the 4.5 rc
cycle, apologize for the inconvenience!
Instead I have this queued for 4.6 and I have added a stable tag to it.

[...]

Kind regards
Uffe

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

* Re: [PATCH 2/2] mmc: tegra: implement memcomp pad calibration
  2016-03-16 11:37     ` Ulf Hansson
@ 2016-03-16 15:04       ` Ulf Hansson
  0 siblings, 0 replies; 10+ messages in thread
From: Ulf Hansson @ 2016-03-16 15:04 UTC (permalink / raw)
  To: Lucas Stach
  Cc: Adrian Hunter, Stephen Warren, Thierry Reding, Alexandre Courbot,
	Jon Hunter, linux-mmc, linux-tegra@vger.kernel.org

On 16 March 2016 at 12:37, Ulf Hansson <ulf.hansson@linaro.org> wrote:
> On 29 February 2016 at 21:56, Lucas Stach <dev@lynxeye.de> wrote:
>> The Tegra30+ SDMMC module has memcomp pads that are used to
>> automatically find and set the correct drive strength settings to
>> the sdmmc pads. The calibration needs to be manually kicked off
>> when the card signal voltage is changed, after the card clock is
>> supplied again.
>>
>> Signed-off-by: Lucas Stach <dev@lynxeye.de>
>
> Thanks applied for next, with a minor trivial fixup to resolve the
> conflict when applying.

I noticed this one also caused a compile error, so I did one more
additional trivial rebase to fix it.

You should probably have look at my next branch, to make sure I
haven't screwed up.

Kind regards
Uffe

>
> Kind regards
> Uffe
>
>> ---
>> This commit allows signal voltage changes on my Tegar30 Beaver to
>> succeed, making UHS-I modes work.
>> ---
>>  drivers/mmc/host/sdhci-tegra.c | 47 +++++++++++++++++++++++++++++++++++++++---
>>  1 file changed, 44 insertions(+), 3 deletions(-)
>>
>> diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c
>> index 46a6bd1..9971732 100644
>> --- a/drivers/mmc/host/sdhci-tegra.c
>> +++ b/drivers/mmc/host/sdhci-tegra.c
>> @@ -12,6 +12,7 @@
>>   *
>>   */
>>
>> +#include "linux/delay.h"
>>  #include <linux/err.h>
>>  #include <linux/module.h>
>>  #include <linux/init.h>
>> @@ -42,12 +43,17 @@
>>  #define SDHCI_MISC_CTRL_ENABLE_SDHCI_SPEC_300  0x20
>>  #define SDHCI_MISC_CTRL_ENABLE_DDR50           0x200
>>
>> +#define SDHCI_TEGRA_AUTO_CAL_CONFIG            0x1e4
>> +#define SDHCI_AUTO_CAL_START                   BIT(31)
>> +#define SDHCI_AUTO_CAL_ENABLE                  BIT(29)
>> +
>>  #define NVQUIRK_FORCE_SDHCI_SPEC_200   BIT(0)
>>  #define NVQUIRK_ENABLE_BLOCK_GAP_DET   BIT(1)
>>  #define NVQUIRK_ENABLE_SDHCI_SPEC_300  BIT(2)
>>  #define NVQUIRK_ENABLE_SDR50           BIT(3)
>>  #define NVQUIRK_ENABLE_SDR104          BIT(4)
>>  #define NVQUIRK_ENABLE_DDR50           BIT(5)
>> +#define NVQUIRK_HAS_PADCALIB           BIT(6)
>>
>>  struct sdhci_tegra_soc_data {
>>         const struct sdhci_pltfm_data *pdata;
>> @@ -58,6 +64,7 @@ struct sdhci_tegra {
>>         const struct sdhci_tegra_soc_data *soc_data;
>>         struct gpio_desc *power_gpio;
>>         bool ddr_signaling;
>> +       bool pad_calib_required;
>>  };
>>
>>  static u16 tegra_sdhci_readw(struct sdhci_host *host, int reg)
>> @@ -165,6 +172,9 @@ static void tegra_sdhci_reset(struct sdhci_host *host, u8 mask)
>>                 clk_ctrl |= SDHCI_CLOCK_CTRL_SDR50_TUNING_OVERRIDE;
>>         sdhci_writel(host, clk_ctrl, SDHCI_TEGRA_VENDOR_CLOCK_CTRL);
>>
>> +       if (soc_data->nvquirks & NVQUIRK_HAS_PADCALIB)
>> +               tegra_host->pad_calib_required = true;
>> +
>>         tegra_host->ddr_signaling = false;
>>  }
>>
>> @@ -187,6 +197,17 @@ static void tegra_sdhci_set_bus_width(struct sdhci_host *host, int bus_width)
>>         sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
>>  }
>>
>> +static void tegra_sdhci_pad_autocalib(struct sdhci_host *host)
>> +{
>> +       u32 val;
>> +
>> +       mdelay(1);
>> +
>> +       val = sdhci_readl(host, SDHCI_TEGRA_AUTO_CAL_CONFIG);
>> +       val |= SDHCI_AUTO_CAL_ENABLE | SDHCI_AUTO_CAL_START;
>> +       sdhci_writel(host,val, SDHCI_TEGRA_AUTO_CAL_CONFIG);
>> +}
>> +
>>  static void tegra_sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
>>  {
>>         struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
>> @@ -200,7 +221,12 @@ static void tegra_sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
>>         clk_set_rate(pltfm_host->clk, host_clk);
>>         host->max_clk = clk_get_rate(pltfm_host->clk);
>>
>> -       return sdhci_set_clock(host, clock);
>> +       sdhci_set_clock(host, clock);
>> +
>> +       if (tegra_host->pad_calib_required) {
>> +               tegra_sdhci_pad_autocalib(host);
>> +               tegra_host->pad_calib_required = false;
>> +       }
>>  }
>>
>>  static void tegra_sdhci_set_uhs_signaling(struct sdhci_host *host,
>> @@ -270,6 +296,16 @@ static int tegra_sdhci_execute_tuning(struct sdhci_host *host, u32 opcode)
>>         return mmc_send_tuning(host->mmc, opcode, NULL);
>>  }
>>
>> +static void tegra_sdhci_voltage_switch(struct sdhci_host *host)
>> +{
>> +       struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
>> +       struct sdhci_tegra *tegra_host = pltfm_host->priv;
>> +       const struct sdhci_tegra_soc_data *soc_data = tegra_host->soc_data;
>> +
>> +       if (soc_data->nvquirks & NVQUIRK_HAS_PADCALIB)
>> +               tegra_host->pad_calib_required = true;
>> +}
>> +
>>  static const struct sdhci_ops tegra_sdhci_ops = {
>>         .get_ro     = tegra_sdhci_get_ro,
>>         .read_w     = tegra_sdhci_readw,
>> @@ -279,6 +315,7 @@ static const struct sdhci_ops tegra_sdhci_ops = {
>>         .reset      = tegra_sdhci_reset,
>>         .platform_execute_tuning = tegra_sdhci_execute_tuning,
>>         .set_uhs_signaling = tegra_sdhci_set_uhs_signaling,
>> +       .voltage_switch = tegra_sdhci_voltage_switch,
>>         .get_max_clock = tegra_sdhci_get_max_clock,
>>  };
>>
>> @@ -312,7 +349,8 @@ static const struct sdhci_tegra_soc_data soc_data_tegra30 = {
>>         .pdata = &sdhci_tegra30_pdata,
>>         .nvquirks = NVQUIRK_ENABLE_SDHCI_SPEC_300 |
>>                     NVQUIRK_ENABLE_SDR50 |
>> -                   NVQUIRK_ENABLE_SDR104,
>> +                   NVQUIRK_ENABLE_SDR104 |
>> +                   NVQUIRK_HAS_PADCALIB,
>>  };
>>
>>  static const struct sdhci_ops tegra114_sdhci_ops = {
>> @@ -325,6 +363,7 @@ static const struct sdhci_ops tegra114_sdhci_ops = {
>>         .reset      = tegra_sdhci_reset,
>>         .platform_execute_tuning = tegra_sdhci_execute_tuning,
>>         .set_uhs_signaling = tegra_sdhci_set_uhs_signaling,
>> +       .voltage_switch = tegra_sdhci_voltage_switch,
>>         .get_max_clock = tegra_sdhci_get_max_clock,
>>  };
>>
>> @@ -347,7 +386,8 @@ static const struct sdhci_tegra_soc_data soc_data_tegra124 = {
>>         .pdata = &sdhci_tegra114_pdata,
>>         .nvquirks = NVQUIRK_ENABLE_SDR50 |
>>                     NVQUIRK_ENABLE_DDR50 |
>> -                   NVQUIRK_ENABLE_SDR104,
>> +                   NVQUIRK_ENABLE_SDR104 |
>> +                   NVQUIRK_HAS_PADCALIB,
>>  };
>>
>>  static const struct sdhci_pltfm_data sdhci_tegra210_pdata = {
>> @@ -402,6 +442,7 @@ static int sdhci_tegra_probe(struct platform_device *pdev)
>>                 goto err_alloc_tegra_host;
>>         }
>>         tegra_host->ddr_signaling = false;
>> +       tegra_host->pad_calib_required = false;
>>         tegra_host->soc_data = soc_data;
>>         pltfm_host->priv = tegra_host;
>>
>> --
>> 2.5.0
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* Re: [PATCH 1/2] mmc: tegra: properly disable card clock
  2016-02-29 20:56 [PATCH 1/2] mmc: tegra: properly disable card clock Lucas Stach
                   ` (2 preceding siblings ...)
  2016-03-04  9:41 ` Ulf Hansson
@ 2016-03-17 11:29 ` Jon Hunter
       [not found]   ` <56EA952B.5020900-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
  3 siblings, 1 reply; 10+ messages in thread
From: Jon Hunter @ 2016-03-17 11:29 UTC (permalink / raw)
  To: Lucas Stach, Ulf Hansson, Adrian Hunter
  Cc: Stephen Warren, Thierry Reding, Alexandre Courbot, linux-mmc,
	linux-tegra


On 29/02/16 20:56, Lucas Stach wrote:
> The new code to do the clock rate setting externally to the SDMMC
> module has a shortcut to not propagate changes with a 0 rate to
> the CAR by simply bailing out. This breaks proper cutting of the
> card clock. Fix it by directly calling the correct sdhci function.
> 
> Fixes: a8e326a911d3 "mmc: tegra: implement module external clock change"
> Signed-off-by: Lucas Stach <dev@lynxeye.de>
> ---
>  drivers/mmc/host/sdhci-tegra.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c
> index 212d51f..46a6bd1 100644
> --- a/drivers/mmc/host/sdhci-tegra.c
> +++ b/drivers/mmc/host/sdhci-tegra.c
> @@ -194,7 +194,7 @@ static void tegra_sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
>  	unsigned long host_clk;
>  
>  	if (!clock)
> -		return;
> +		return sdhci_set_clock(host, clock);;

Looks like the above adds an unnecessary additional semi-colon.

Ulf, are you able to correct, or do you want a patch?

Cheers
Jon

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

* Re: [PATCH 1/2] mmc: tegra: properly disable card clock
       [not found]   ` <56EA952B.5020900-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
@ 2016-03-17 13:55     ` Ulf Hansson
  0 siblings, 0 replies; 10+ messages in thread
From: Ulf Hansson @ 2016-03-17 13:55 UTC (permalink / raw)
  To: Jon Hunter
  Cc: Lucas Stach, Adrian Hunter, Stephen Warren, Thierry Reding,
	Alexandre Courbot, linux-mmc,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org

On 17 March 2016 at 12:29, Jon Hunter <jonathanh-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org> wrote:
>
> On 29/02/16 20:56, Lucas Stach wrote:
>> The new code to do the clock rate setting externally to the SDMMC
>> module has a shortcut to not propagate changes with a 0 rate to
>> the CAR by simply bailing out. This breaks proper cutting of the
>> card clock. Fix it by directly calling the correct sdhci function.
>>
>> Fixes: a8e326a911d3 "mmc: tegra: implement module external clock change"
>> Signed-off-by: Lucas Stach <dev-8ppwABl0HbeELgA04lAiVw@public.gmane.org>
>> ---
>>  drivers/mmc/host/sdhci-tegra.c | 2 +-
>>  1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c
>> index 212d51f..46a6bd1 100644
>> --- a/drivers/mmc/host/sdhci-tegra.c
>> +++ b/drivers/mmc/host/sdhci-tegra.c
>> @@ -194,7 +194,7 @@ static void tegra_sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
>>       unsigned long host_clk;
>>
>>       if (!clock)
>> -             return;
>> +             return sdhci_set_clock(host, clock);;
>
> Looks like the above adds an unnecessary additional semi-colon.
>
> Ulf, are you able to correct, or do you want a patch?

Thanks for spotting this, I have amended the commit. No patch needed.

Thanks!

Kind regards
Uffe

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

end of thread, other threads:[~2016-03-17 13:55 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-02-29 20:56 [PATCH 1/2] mmc: tegra: properly disable card clock Lucas Stach
     [not found] ` <1456779385-18996-1-git-send-email-dev-8ppwABl0HbeELgA04lAiVw@public.gmane.org>
2016-02-29 20:56   ` [PATCH 2/2] mmc: tegra: implement memcomp pad calibration Lucas Stach
2016-03-04 13:02     ` Adrian Hunter
2016-03-16 11:37     ` Ulf Hansson
2016-03-16 15:04       ` Ulf Hansson
2016-03-03 14:06 ` [PATCH 1/2] mmc: tegra: properly disable card clock Adrian Hunter
2016-03-04  9:41 ` Ulf Hansson
     [not found]   ` <CAPDyKFoJfNE7HcL3BcbRQpw6uOvQYrD=bEYvgUxjvOaX36o=fA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2016-03-16 12:35     ` Ulf Hansson
2016-03-17 11:29 ` Jon Hunter
     [not found]   ` <56EA952B.5020900-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2016-03-17 13:55     ` 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).