All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 00/10] Tegra SDHCI update the pad autocal procedure
@ 2018-07-26 12:26 ` Aapo Vienamo
  0 siblings, 0 replies; 29+ messages in thread
From: Aapo Vienamo @ 2018-07-26 12:26 UTC (permalink / raw)
  To: Ulf Hansson, Rob Herring, Mark Rutland, Thierry Reding,
	Jonathan Hunter, Adrian Hunter, Mikko Perttunen
  Cc: linux-mmc, devicetree, linux-tegra, linux-kernel, Aapo Vienamo

Hi all,

Update the tegra_sdhci_pad_autocalib() pad drive strength calibration
procedure to match the ones specified in the TRMs of the more recent
SoCs. This was tested on Tegra186, Tegra210, and Tegra124, although it
should not break things older generations either.

This series depends on the "Tegra SDHCI enable 1.8 V signaling on
Tegar210 and Tegra186" series posted earlier.

Changelog:
v2:
	- Rename the series
	- Align the register macros
	- Use readl_poll_timeout() in tegra_sdhci_pad_autocalib()
	- Move SDHCI_TEGRA_PAD_E_INPUT_OR_E_PWRD define to correc patch
	- Use !!(reg & SDHCI_CLOCK_CARD_EN) in
	  tegra_sdhci_configure_card_clk()
	- Add "nvidia," prefix to pad drive strength offset dt props
	- Read the drive strength properties as u32 instead of u8
	- Disable autocalibration if it times out

Aapo Vienamo (10):
  mmc: tegra: Poll for calibration completion
  mmc: tegra: Set calibration pad voltage reference
  mmc: tegra: Power on the calibration pad
  mmc: tegra: Disable card clock during pad calibration
  dt-bindings: Add Tegra SDHCI pad pdpu offset bindings
  mmc: tegra: Program pad autocal offsets from dt
  arm64: dts: tegra186: Add sdmmc pad auto calibration offsets
  arm64: dts: tegra210: Add sdmmc pad auto calibration offsets
  mmc: tegra: Perform pad calibration after voltage switch
  mmc: tegra: Enable pad calibration on Tegra210 and Tegra186

 .../bindings/mmc/nvidia,tegra20-sdhci.txt          |  34 +++
 arch/arm64/boot/dts/nvidia/tegra186.dtsi           |  20 ++
 arch/arm64/boot/dts/nvidia/tegra210.dtsi           |  12 +
 drivers/mmc/host/sdhci-tegra.c                     | 280 +++++++++++++++++++--
 4 files changed, 319 insertions(+), 27 deletions(-)

-- 
2.7.4

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

* [PATCH v2 00/10] Tegra SDHCI update the pad autocal procedure
@ 2018-07-26 12:26 ` Aapo Vienamo
  0 siblings, 0 replies; 29+ messages in thread
From: Aapo Vienamo @ 2018-07-26 12:26 UTC (permalink / raw)
  To: Ulf Hansson, Rob Herring, Mark Rutland, Thierry Reding,
	Jonathan Hunter, Adrian Hunter, Mikko Perttunen
  Cc: linux-mmc, devicetree, linux-tegra, linux-kernel, Aapo Vienamo

Hi all,

Update the tegra_sdhci_pad_autocalib() pad drive strength calibration
procedure to match the ones specified in the TRMs of the more recent
SoCs. This was tested on Tegra186, Tegra210, and Tegra124, although it
should not break things older generations either.

This series depends on the "Tegra SDHCI enable 1.8 V signaling on
Tegar210 and Tegra186" series posted earlier.

Changelog:
v2:
	- Rename the series
	- Align the register macros
	- Use readl_poll_timeout() in tegra_sdhci_pad_autocalib()
	- Move SDHCI_TEGRA_PAD_E_INPUT_OR_E_PWRD define to correc patch
	- Use !!(reg & SDHCI_CLOCK_CARD_EN) in
	  tegra_sdhci_configure_card_clk()
	- Add "nvidia," prefix to pad drive strength offset dt props
	- Read the drive strength properties as u32 instead of u8
	- Disable autocalibration if it times out

Aapo Vienamo (10):
  mmc: tegra: Poll for calibration completion
  mmc: tegra: Set calibration pad voltage reference
  mmc: tegra: Power on the calibration pad
  mmc: tegra: Disable card clock during pad calibration
  dt-bindings: Add Tegra SDHCI pad pdpu offset bindings
  mmc: tegra: Program pad autocal offsets from dt
  arm64: dts: tegra186: Add sdmmc pad auto calibration offsets
  arm64: dts: tegra210: Add sdmmc pad auto calibration offsets
  mmc: tegra: Perform pad calibration after voltage switch
  mmc: tegra: Enable pad calibration on Tegra210 and Tegra186

 .../bindings/mmc/nvidia,tegra20-sdhci.txt          |  34 +++
 arch/arm64/boot/dts/nvidia/tegra186.dtsi           |  20 ++
 arch/arm64/boot/dts/nvidia/tegra210.dtsi           |  12 +
 drivers/mmc/host/sdhci-tegra.c                     | 280 +++++++++++++++++++--
 4 files changed, 319 insertions(+), 27 deletions(-)

-- 
2.7.4


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

* [PATCH v2 01/10] mmc: tegra: Poll for calibration completion
  2018-07-26 12:26 ` Aapo Vienamo
@ 2018-07-26 12:26   ` Aapo Vienamo
  -1 siblings, 0 replies; 29+ messages in thread
From: Aapo Vienamo @ 2018-07-26 12:26 UTC (permalink / raw)
  To: Ulf Hansson, Rob Herring, Mark Rutland, Thierry Reding,
	Jonathan Hunter, Adrian Hunter, Mikko Perttunen
  Cc: linux-mmc, devicetree, linux-tegra, linux-kernel, Aapo Vienamo

Implement polling with 10 ms timeout for automatic pad drive strength
calibration.

Signed-off-by: Aapo Vienamo <avienamo@nvidia.com>
---
 drivers/mmc/host/sdhci-tegra.c | 21 ++++++++++++++++-----
 1 file changed, 16 insertions(+), 5 deletions(-)

diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c
index 9587365..27b5ef9 100644
--- a/drivers/mmc/host/sdhci-tegra.c
+++ b/drivers/mmc/host/sdhci-tegra.c
@@ -16,6 +16,7 @@
 #include <linux/err.h>
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/iopoll.h>
 #include <linux/platform_device.h>
 #include <linux/clk.h>
 #include <linux/io.h>
@@ -49,6 +50,9 @@
 #define SDHCI_AUTO_CAL_START			BIT(31)
 #define SDHCI_AUTO_CAL_ENABLE			BIT(29)
 
+#define SDHCI_TEGRA_AUTO_CAL_STATUS		0x1ec
+#define SDHCI_TEGRA_AUTO_CAL_ACTIVE		BIT(31)
+
 #define NVQUIRK_FORCE_SDHCI_SPEC_200	BIT(0)
 #define NVQUIRK_ENABLE_BLOCK_GAP_DET	BIT(1)
 #define NVQUIRK_ENABLE_SDHCI_SPEC_300	BIT(2)
@@ -229,13 +233,20 @@ static void tegra_sdhci_reset(struct sdhci_host *host, u8 mask)
 
 static void tegra_sdhci_pad_autocalib(struct sdhci_host *host)
 {
-	u32 val;
+	u32 reg;
+	int ret;
+
+	reg = sdhci_readl(host, SDHCI_TEGRA_AUTO_CAL_CONFIG);
+	reg |= SDHCI_AUTO_CAL_ENABLE | SDHCI_AUTO_CAL_START;
+	sdhci_writel(host, reg, SDHCI_TEGRA_AUTO_CAL_CONFIG);
 
-	mdelay(1);
+	/* 10 ms timeout */
+	ret = readl_poll_timeout(host->ioaddr + SDHCI_TEGRA_AUTO_CAL_STATUS,
+				 reg, !(reg & SDHCI_TEGRA_AUTO_CAL_ACTIVE),
+				 1, 10000);
 
-	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);
+	if (ret)
+		dev_err(mmc_dev(host->mmc), "Pad autocal timed out\n");
 }
 
 static void tegra_sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
-- 
2.7.4

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

* [PATCH v2 01/10] mmc: tegra: Poll for calibration completion
@ 2018-07-26 12:26   ` Aapo Vienamo
  0 siblings, 0 replies; 29+ messages in thread
From: Aapo Vienamo @ 2018-07-26 12:26 UTC (permalink / raw)
  To: Ulf Hansson, Rob Herring, Mark Rutland, Thierry Reding,
	Jonathan Hunter, Adrian Hunter, Mikko Perttunen
  Cc: linux-mmc, devicetree, linux-tegra, linux-kernel, Aapo Vienamo

Implement polling with 10 ms timeout for automatic pad drive strength
calibration.

Signed-off-by: Aapo Vienamo <avienamo@nvidia.com>
---
 drivers/mmc/host/sdhci-tegra.c | 21 ++++++++++++++++-----
 1 file changed, 16 insertions(+), 5 deletions(-)

diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c
index 9587365..27b5ef9 100644
--- a/drivers/mmc/host/sdhci-tegra.c
+++ b/drivers/mmc/host/sdhci-tegra.c
@@ -16,6 +16,7 @@
 #include <linux/err.h>
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/iopoll.h>
 #include <linux/platform_device.h>
 #include <linux/clk.h>
 #include <linux/io.h>
@@ -49,6 +50,9 @@
 #define SDHCI_AUTO_CAL_START			BIT(31)
 #define SDHCI_AUTO_CAL_ENABLE			BIT(29)
 
+#define SDHCI_TEGRA_AUTO_CAL_STATUS		0x1ec
+#define SDHCI_TEGRA_AUTO_CAL_ACTIVE		BIT(31)
+
 #define NVQUIRK_FORCE_SDHCI_SPEC_200	BIT(0)
 #define NVQUIRK_ENABLE_BLOCK_GAP_DET	BIT(1)
 #define NVQUIRK_ENABLE_SDHCI_SPEC_300	BIT(2)
@@ -229,13 +233,20 @@ static void tegra_sdhci_reset(struct sdhci_host *host, u8 mask)
 
 static void tegra_sdhci_pad_autocalib(struct sdhci_host *host)
 {
-	u32 val;
+	u32 reg;
+	int ret;
+
+	reg = sdhci_readl(host, SDHCI_TEGRA_AUTO_CAL_CONFIG);
+	reg |= SDHCI_AUTO_CAL_ENABLE | SDHCI_AUTO_CAL_START;
+	sdhci_writel(host, reg, SDHCI_TEGRA_AUTO_CAL_CONFIG);
 
-	mdelay(1);
+	/* 10 ms timeout */
+	ret = readl_poll_timeout(host->ioaddr + SDHCI_TEGRA_AUTO_CAL_STATUS,
+				 reg, !(reg & SDHCI_TEGRA_AUTO_CAL_ACTIVE),
+				 1, 10000);
 
-	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);
+	if (ret)
+		dev_err(mmc_dev(host->mmc), "Pad autocal timed out\n");
 }
 
 static void tegra_sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
-- 
2.7.4


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

* [PATCH v2 02/10] mmc: tegra: Set calibration pad voltage reference
  2018-07-26 12:26 ` Aapo Vienamo
@ 2018-07-26 12:26   ` Aapo Vienamo
  -1 siblings, 0 replies; 29+ messages in thread
From: Aapo Vienamo @ 2018-07-26 12:26 UTC (permalink / raw)
  To: Ulf Hansson, Rob Herring, Mark Rutland, Thierry Reding,
	Jonathan Hunter, Adrian Hunter, Mikko Perttunen
  Cc: linux-mmc, devicetree, linux-tegra, linux-kernel, Aapo Vienamo

Configure the voltage reference used by the automatic pad drive strength
calibration procedure. The value is a magic number from the TRM.

Signed-off-by: Aapo Vienamo <avienamo@nvidia.com>
---
 drivers/mmc/host/sdhci-tegra.c | 56 +++++++++++++++++++++++++-----------------
 1 file changed, 33 insertions(+), 23 deletions(-)

diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c
index 27b5ef9..51eda20 100644
--- a/drivers/mmc/host/sdhci-tegra.c
+++ b/drivers/mmc/host/sdhci-tegra.c
@@ -40,27 +40,31 @@
 #define SDHCI_CLOCK_CTRL_PADPIPE_CLKEN_OVERRIDE		BIT(3)
 #define SDHCI_CLOCK_CTRL_SPI_MODE_CLKEN_OVERRIDE	BIT(2)
 
-#define SDHCI_TEGRA_VENDOR_MISC_CTRL		0x120
-#define SDHCI_MISC_CTRL_ENABLE_SDR104		0x8
-#define SDHCI_MISC_CTRL_ENABLE_SDR50		0x10
-#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 SDHCI_TEGRA_AUTO_CAL_STATUS		0x1ec
-#define SDHCI_TEGRA_AUTO_CAL_ACTIVE		BIT(31)
-
-#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)
-#define NVQUIRK_NEEDS_PAD_CONTROL	BIT(7)
+#define SDHCI_TEGRA_VENDOR_MISC_CTRL			0x120
+#define SDHCI_MISC_CTRL_ENABLE_SDR104			0x8
+#define SDHCI_MISC_CTRL_ENABLE_SDR50			0x10
+#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 SDHCI_TEGRA_SDMEM_COMP_PADCTRL			0x1e0
+#define SDHCI_TEGRA_SDMEM_COMP_PADCTRL_VREF_SEL_MASK	0x0000000f
+#define SDHCI_TEGRA_SDMEM_COMP_PADCTRL_VREF_SEL_VAL	0x7
+
+#define SDHCI_TEGRA_AUTO_CAL_STATUS			0x1ec
+#define SDHCI_TEGRA_AUTO_CAL_ACTIVE			BIT(31)
+
+#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)
+#define NVQUIRK_NEEDS_PAD_CONTROL			BIT(7)
 
 struct sdhci_tegra_soc_data {
 	const struct sdhci_pltfm_data *pdata;
@@ -188,7 +192,7 @@ static void tegra_sdhci_reset(struct sdhci_host *host, u8 mask)
 	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
 	struct sdhci_tegra *tegra_host = sdhci_pltfm_priv(pltfm_host);
 	const struct sdhci_tegra_soc_data *soc_data = tegra_host->soc_data;
-	u32 misc_ctrl, clk_ctrl;
+	u32 misc_ctrl, clk_ctrl, pad_ctrl;
 	bool uhs_valid;
 
 	sdhci_reset(host, mask);
@@ -225,8 +229,14 @@ static void tegra_sdhci_reset(struct sdhci_host *host, u8 mask)
 	sdhci_writel(host, misc_ctrl, SDHCI_TEGRA_VENDOR_MISC_CTRL);
 	sdhci_writel(host, clk_ctrl, SDHCI_TEGRA_VENDOR_CLOCK_CTRL);
 
-	if (soc_data->nvquirks & NVQUIRK_HAS_PADCALIB)
+	if (soc_data->nvquirks & NVQUIRK_HAS_PADCALIB) {
+		pad_ctrl = sdhci_readl(host, SDHCI_TEGRA_SDMEM_COMP_PADCTRL);
+		pad_ctrl &= ~SDHCI_TEGRA_SDMEM_COMP_PADCTRL_VREF_SEL_MASK;
+		pad_ctrl |= SDHCI_TEGRA_SDMEM_COMP_PADCTRL_VREF_SEL_VAL;
+		sdhci_writel(host, pad_ctrl, SDHCI_TEGRA_SDMEM_COMP_PADCTRL);
+
 		tegra_host->pad_calib_required = true;
+	}
 
 	tegra_host->ddr_signaling = false;
 }
-- 
2.7.4

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

* [PATCH v2 02/10] mmc: tegra: Set calibration pad voltage reference
@ 2018-07-26 12:26   ` Aapo Vienamo
  0 siblings, 0 replies; 29+ messages in thread
From: Aapo Vienamo @ 2018-07-26 12:26 UTC (permalink / raw)
  To: Ulf Hansson, Rob Herring, Mark Rutland, Thierry Reding,
	Jonathan Hunter, Adrian Hunter, Mikko Perttunen
  Cc: linux-mmc, devicetree, linux-tegra, linux-kernel, Aapo Vienamo

Configure the voltage reference used by the automatic pad drive strength
calibration procedure. The value is a magic number from the TRM.

Signed-off-by: Aapo Vienamo <avienamo@nvidia.com>
---
 drivers/mmc/host/sdhci-tegra.c | 56 +++++++++++++++++++++++++-----------------
 1 file changed, 33 insertions(+), 23 deletions(-)

diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c
index 27b5ef9..51eda20 100644
--- a/drivers/mmc/host/sdhci-tegra.c
+++ b/drivers/mmc/host/sdhci-tegra.c
@@ -40,27 +40,31 @@
 #define SDHCI_CLOCK_CTRL_PADPIPE_CLKEN_OVERRIDE		BIT(3)
 #define SDHCI_CLOCK_CTRL_SPI_MODE_CLKEN_OVERRIDE	BIT(2)
 
-#define SDHCI_TEGRA_VENDOR_MISC_CTRL		0x120
-#define SDHCI_MISC_CTRL_ENABLE_SDR104		0x8
-#define SDHCI_MISC_CTRL_ENABLE_SDR50		0x10
-#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 SDHCI_TEGRA_AUTO_CAL_STATUS		0x1ec
-#define SDHCI_TEGRA_AUTO_CAL_ACTIVE		BIT(31)
-
-#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)
-#define NVQUIRK_NEEDS_PAD_CONTROL	BIT(7)
+#define SDHCI_TEGRA_VENDOR_MISC_CTRL			0x120
+#define SDHCI_MISC_CTRL_ENABLE_SDR104			0x8
+#define SDHCI_MISC_CTRL_ENABLE_SDR50			0x10
+#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 SDHCI_TEGRA_SDMEM_COMP_PADCTRL			0x1e0
+#define SDHCI_TEGRA_SDMEM_COMP_PADCTRL_VREF_SEL_MASK	0x0000000f
+#define SDHCI_TEGRA_SDMEM_COMP_PADCTRL_VREF_SEL_VAL	0x7
+
+#define SDHCI_TEGRA_AUTO_CAL_STATUS			0x1ec
+#define SDHCI_TEGRA_AUTO_CAL_ACTIVE			BIT(31)
+
+#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)
+#define NVQUIRK_NEEDS_PAD_CONTROL			BIT(7)
 
 struct sdhci_tegra_soc_data {
 	const struct sdhci_pltfm_data *pdata;
@@ -188,7 +192,7 @@ static void tegra_sdhci_reset(struct sdhci_host *host, u8 mask)
 	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
 	struct sdhci_tegra *tegra_host = sdhci_pltfm_priv(pltfm_host);
 	const struct sdhci_tegra_soc_data *soc_data = tegra_host->soc_data;
-	u32 misc_ctrl, clk_ctrl;
+	u32 misc_ctrl, clk_ctrl, pad_ctrl;
 	bool uhs_valid;
 
 	sdhci_reset(host, mask);
@@ -225,8 +229,14 @@ static void tegra_sdhci_reset(struct sdhci_host *host, u8 mask)
 	sdhci_writel(host, misc_ctrl, SDHCI_TEGRA_VENDOR_MISC_CTRL);
 	sdhci_writel(host, clk_ctrl, SDHCI_TEGRA_VENDOR_CLOCK_CTRL);
 
-	if (soc_data->nvquirks & NVQUIRK_HAS_PADCALIB)
+	if (soc_data->nvquirks & NVQUIRK_HAS_PADCALIB) {
+		pad_ctrl = sdhci_readl(host, SDHCI_TEGRA_SDMEM_COMP_PADCTRL);
+		pad_ctrl &= ~SDHCI_TEGRA_SDMEM_COMP_PADCTRL_VREF_SEL_MASK;
+		pad_ctrl |= SDHCI_TEGRA_SDMEM_COMP_PADCTRL_VREF_SEL_VAL;
+		sdhci_writel(host, pad_ctrl, SDHCI_TEGRA_SDMEM_COMP_PADCTRL);
+
 		tegra_host->pad_calib_required = true;
+	}
 
 	tegra_host->ddr_signaling = false;
 }
-- 
2.7.4


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

* [PATCH v2 03/10] mmc: tegra: Power on the calibration pad
  2018-07-26 12:26 ` Aapo Vienamo
@ 2018-07-26 12:26   ` Aapo Vienamo
  -1 siblings, 0 replies; 29+ messages in thread
From: Aapo Vienamo @ 2018-07-26 12:26 UTC (permalink / raw)
  To: Ulf Hansson, Rob Herring, Mark Rutland, Thierry Reding,
	Jonathan Hunter, Adrian Hunter, Mikko Perttunen
  Cc: linux-mmc, devicetree, linux-tegra, linux-kernel, Aapo Vienamo

Automatic pad drive strength calibration is performed on a separate pad
identical to the ones used for driving the actual bus. Power on the
calibration pad during the calibration procedure and power it off
afterwards to save power.

Signed-off-by: Aapo Vienamo <avienamo@nvidia.com>
Reviewed-by: Mikko Perttunen <mperttunen@nvidia.com>
---
 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 51eda20..363490e 100644
--- a/drivers/mmc/host/sdhci-tegra.c
+++ b/drivers/mmc/host/sdhci-tegra.c
@@ -53,6 +53,7 @@
 #define SDHCI_TEGRA_SDMEM_COMP_PADCTRL			0x1e0
 #define SDHCI_TEGRA_SDMEM_COMP_PADCTRL_VREF_SEL_MASK	0x0000000f
 #define SDHCI_TEGRA_SDMEM_COMP_PADCTRL_VREF_SEL_VAL	0x7
+#define SDHCI_TEGRA_SDMEM_COMP_PADCTRL_E_INPUT_E_PWRD	BIT(31)
 
 #define SDHCI_TEGRA_AUTO_CAL_STATUS			0x1ec
 #define SDHCI_TEGRA_AUTO_CAL_ACTIVE			BIT(31)
@@ -241,11 +242,30 @@ static void tegra_sdhci_reset(struct sdhci_host *host, u8 mask)
 	tegra_host->ddr_signaling = false;
 }
 
+static void tegra_sdhci_configure_cal_pad(struct sdhci_host *host, bool enable)
+{
+	u32 reg;
+
+	/*
+	 * Enable or disable the additional I/O pad used by the drive strength
+	 * calibration process.
+	 */
+	reg = sdhci_readl(host, SDHCI_TEGRA_SDMEM_COMP_PADCTRL);
+	if (enable)
+		reg |= SDHCI_TEGRA_SDMEM_COMP_PADCTRL_E_INPUT_E_PWRD;
+	else
+		reg &= ~SDHCI_TEGRA_SDMEM_COMP_PADCTRL_E_INPUT_E_PWRD;
+	sdhci_writel(host, reg, SDHCI_TEGRA_SDMEM_COMP_PADCTRL);
+	udelay(1);
+}
+
 static void tegra_sdhci_pad_autocalib(struct sdhci_host *host)
 {
 	u32 reg;
 	int ret;
 
+	tegra_sdhci_configure_cal_pad(host, true);
+
 	reg = sdhci_readl(host, SDHCI_TEGRA_AUTO_CAL_CONFIG);
 	reg |= SDHCI_AUTO_CAL_ENABLE | SDHCI_AUTO_CAL_START;
 	sdhci_writel(host, reg, SDHCI_TEGRA_AUTO_CAL_CONFIG);
@@ -255,6 +275,8 @@ static void tegra_sdhci_pad_autocalib(struct sdhci_host *host)
 				 reg, !(reg & SDHCI_TEGRA_AUTO_CAL_ACTIVE),
 				 1, 10000);
 
+	tegra_sdhci_configure_cal_pad(host, false);
+
 	if (ret)
 		dev_err(mmc_dev(host->mmc), "Pad autocal timed out\n");
 }
-- 
2.7.4

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

* [PATCH v2 03/10] mmc: tegra: Power on the calibration pad
@ 2018-07-26 12:26   ` Aapo Vienamo
  0 siblings, 0 replies; 29+ messages in thread
From: Aapo Vienamo @ 2018-07-26 12:26 UTC (permalink / raw)
  To: Ulf Hansson, Rob Herring, Mark Rutland, Thierry Reding,
	Jonathan Hunter, Adrian Hunter, Mikko Perttunen
  Cc: linux-mmc, devicetree, linux-tegra, linux-kernel, Aapo Vienamo

Automatic pad drive strength calibration is performed on a separate pad
identical to the ones used for driving the actual bus. Power on the
calibration pad during the calibration procedure and power it off
afterwards to save power.

Signed-off-by: Aapo Vienamo <avienamo@nvidia.com>
Reviewed-by: Mikko Perttunen <mperttunen@nvidia.com>
---
 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 51eda20..363490e 100644
--- a/drivers/mmc/host/sdhci-tegra.c
+++ b/drivers/mmc/host/sdhci-tegra.c
@@ -53,6 +53,7 @@
 #define SDHCI_TEGRA_SDMEM_COMP_PADCTRL			0x1e0
 #define SDHCI_TEGRA_SDMEM_COMP_PADCTRL_VREF_SEL_MASK	0x0000000f
 #define SDHCI_TEGRA_SDMEM_COMP_PADCTRL_VREF_SEL_VAL	0x7
+#define SDHCI_TEGRA_SDMEM_COMP_PADCTRL_E_INPUT_E_PWRD	BIT(31)
 
 #define SDHCI_TEGRA_AUTO_CAL_STATUS			0x1ec
 #define SDHCI_TEGRA_AUTO_CAL_ACTIVE			BIT(31)
@@ -241,11 +242,30 @@ static void tegra_sdhci_reset(struct sdhci_host *host, u8 mask)
 	tegra_host->ddr_signaling = false;
 }
 
+static void tegra_sdhci_configure_cal_pad(struct sdhci_host *host, bool enable)
+{
+	u32 reg;
+
+	/*
+	 * Enable or disable the additional I/O pad used by the drive strength
+	 * calibration process.
+	 */
+	reg = sdhci_readl(host, SDHCI_TEGRA_SDMEM_COMP_PADCTRL);
+	if (enable)
+		reg |= SDHCI_TEGRA_SDMEM_COMP_PADCTRL_E_INPUT_E_PWRD;
+	else
+		reg &= ~SDHCI_TEGRA_SDMEM_COMP_PADCTRL_E_INPUT_E_PWRD;
+	sdhci_writel(host, reg, SDHCI_TEGRA_SDMEM_COMP_PADCTRL);
+	udelay(1);
+}
+
 static void tegra_sdhci_pad_autocalib(struct sdhci_host *host)
 {
 	u32 reg;
 	int ret;
 
+	tegra_sdhci_configure_cal_pad(host, true);
+
 	reg = sdhci_readl(host, SDHCI_TEGRA_AUTO_CAL_CONFIG);
 	reg |= SDHCI_AUTO_CAL_ENABLE | SDHCI_AUTO_CAL_START;
 	sdhci_writel(host, reg, SDHCI_TEGRA_AUTO_CAL_CONFIG);
@@ -255,6 +275,8 @@ static void tegra_sdhci_pad_autocalib(struct sdhci_host *host)
 				 reg, !(reg & SDHCI_TEGRA_AUTO_CAL_ACTIVE),
 				 1, 10000);
 
+	tegra_sdhci_configure_cal_pad(host, false);
+
 	if (ret)
 		dev_err(mmc_dev(host->mmc), "Pad autocal timed out\n");
 }
-- 
2.7.4


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

* [PATCH v2 04/10] mmc: tegra: Disable card clock during pad calibration
  2018-07-26 12:26 ` Aapo Vienamo
@ 2018-07-26 12:26   ` Aapo Vienamo
  -1 siblings, 0 replies; 29+ messages in thread
From: Aapo Vienamo @ 2018-07-26 12:26 UTC (permalink / raw)
  To: Ulf Hansson, Rob Herring, Mark Rutland, Thierry Reding,
	Jonathan Hunter, Adrian Hunter, Mikko Perttunen
  Cc: linux-mmc, devicetree, linux-tegra, linux-kernel, Aapo Vienamo

Disable the card clock during automatic pad drive strength calibration
and re-enable it afterwards.

Signed-off-by: Aapo Vienamo <avienamo@nvidia.com>
---
 drivers/mmc/host/sdhci-tegra.c | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c
index 363490e..79ecdd0 100644
--- a/drivers/mmc/host/sdhci-tegra.c
+++ b/drivers/mmc/host/sdhci-tegra.c
@@ -259,11 +259,35 @@ static void tegra_sdhci_configure_cal_pad(struct sdhci_host *host, bool enable)
 	udelay(1);
 }
 
+static bool tegra_sdhci_configure_card_clk(struct sdhci_host *host, bool enable)
+{
+	bool orig_enabled;
+	u32 reg;
+
+	reg = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
+	orig_enabled = !!(reg & SDHCI_CLOCK_CARD_EN);
+
+	if (orig_enabled == enable)
+		return orig_enabled;
+
+	if (enable)
+		reg |= SDHCI_CLOCK_CARD_EN;
+	else
+		reg &= ~SDHCI_CLOCK_CARD_EN;
+
+	sdhci_writew(host, reg, SDHCI_CLOCK_CONTROL);
+
+	return orig_enabled;
+}
+
 static void tegra_sdhci_pad_autocalib(struct sdhci_host *host)
 {
+	bool card_clk_enabled;
 	u32 reg;
 	int ret;
 
+	card_clk_enabled = tegra_sdhci_configure_card_clk(host, false);
+
 	tegra_sdhci_configure_cal_pad(host, true);
 
 	reg = sdhci_readl(host, SDHCI_TEGRA_AUTO_CAL_CONFIG);
@@ -277,6 +301,8 @@ static void tegra_sdhci_pad_autocalib(struct sdhci_host *host)
 
 	tegra_sdhci_configure_cal_pad(host, false);
 
+	tegra_sdhci_configure_card_clk(host, card_clk_enabled);
+
 	if (ret)
 		dev_err(mmc_dev(host->mmc), "Pad autocal timed out\n");
 }
-- 
2.7.4

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

* [PATCH v2 04/10] mmc: tegra: Disable card clock during pad calibration
@ 2018-07-26 12:26   ` Aapo Vienamo
  0 siblings, 0 replies; 29+ messages in thread
From: Aapo Vienamo @ 2018-07-26 12:26 UTC (permalink / raw)
  To: Ulf Hansson, Rob Herring, Mark Rutland, Thierry Reding,
	Jonathan Hunter, Adrian Hunter, Mikko Perttunen
  Cc: linux-mmc, devicetree, linux-tegra, linux-kernel, Aapo Vienamo

Disable the card clock during automatic pad drive strength calibration
and re-enable it afterwards.

Signed-off-by: Aapo Vienamo <avienamo@nvidia.com>
---
 drivers/mmc/host/sdhci-tegra.c | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c
index 363490e..79ecdd0 100644
--- a/drivers/mmc/host/sdhci-tegra.c
+++ b/drivers/mmc/host/sdhci-tegra.c
@@ -259,11 +259,35 @@ static void tegra_sdhci_configure_cal_pad(struct sdhci_host *host, bool enable)
 	udelay(1);
 }
 
+static bool tegra_sdhci_configure_card_clk(struct sdhci_host *host, bool enable)
+{
+	bool orig_enabled;
+	u32 reg;
+
+	reg = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
+	orig_enabled = !!(reg & SDHCI_CLOCK_CARD_EN);
+
+	if (orig_enabled == enable)
+		return orig_enabled;
+
+	if (enable)
+		reg |= SDHCI_CLOCK_CARD_EN;
+	else
+		reg &= ~SDHCI_CLOCK_CARD_EN;
+
+	sdhci_writew(host, reg, SDHCI_CLOCK_CONTROL);
+
+	return orig_enabled;
+}
+
 static void tegra_sdhci_pad_autocalib(struct sdhci_host *host)
 {
+	bool card_clk_enabled;
 	u32 reg;
 	int ret;
 
+	card_clk_enabled = tegra_sdhci_configure_card_clk(host, false);
+
 	tegra_sdhci_configure_cal_pad(host, true);
 
 	reg = sdhci_readl(host, SDHCI_TEGRA_AUTO_CAL_CONFIG);
@@ -277,6 +301,8 @@ static void tegra_sdhci_pad_autocalib(struct sdhci_host *host)
 
 	tegra_sdhci_configure_cal_pad(host, false);
 
+	tegra_sdhci_configure_card_clk(host, card_clk_enabled);
+
 	if (ret)
 		dev_err(mmc_dev(host->mmc), "Pad autocal timed out\n");
 }
-- 
2.7.4


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

* [PATCH v2 05/10] dt-bindings: Add Tegra SDHCI pad pdpu offset bindings
  2018-07-26 12:26 ` Aapo Vienamo
@ 2018-07-26 12:26   ` Aapo Vienamo
  -1 siblings, 0 replies; 29+ messages in thread
From: Aapo Vienamo @ 2018-07-26 12:26 UTC (permalink / raw)
  To: Ulf Hansson, Rob Herring, Mark Rutland, Thierry Reding,
	Jonathan Hunter, Adrian Hunter, Mikko Perttunen
  Cc: linux-mmc, devicetree, linux-tegra, linux-kernel, Aapo Vienamo

Add bindings documentation for pad pull up and pull down offset values to be
programmed before executing automatic pad drive strength calibration.

Signed-off-by: Aapo Vienamo <avienamo@nvidia.com>
---
 .../bindings/mmc/nvidia,tegra20-sdhci.txt          | 34 ++++++++++++++++++++++
 1 file changed, 34 insertions(+)

diff --git a/Documentation/devicetree/bindings/mmc/nvidia,tegra20-sdhci.txt b/Documentation/devicetree/bindings/mmc/nvidia,tegra20-sdhci.txt
index 95010cf..c3d8a15 100644
--- a/Documentation/devicetree/bindings/mmc/nvidia,tegra20-sdhci.txt
+++ b/Documentation/devicetree/bindings/mmc/nvidia,tegra20-sdhci.txt
@@ -24,6 +24,7 @@ Required properties:
 Optional properties:
 - power-gpios : Specify GPIOs for power control
 
+Optional properties for Tegra210 and Tegra186:
 Example:
 
 sdhci@c8000200 {
@@ -47,6 +48,35 @@ Optional properties for Tegra210 and Tegra186:
   pinctrl-1.
 - nvidia,only-1-8-v : The presence of this property indicates that the
   controller operates at a 1.8 V fixed I/O voltage.
+- nvidia,pad-autocal-pull-up-offset-3v3,
+  nvidia,pad-autocal-pull-down-offset-3v3 : Specify drive strength
+  calibration offsets for 3.3 V signaling modes.
+- nvidia,pad-autocal-pull-up-offset-1v8,
+  nvidia,pad-autocal-pull-down-offset-1v8 : Specify drive strength
+  calibration offsets for 1.8 V signaling modes.
+- nvidia,pad-autocal-pull-up-offset-3v3-timeout,
+  nvidia,pad-autocal-pull-down-offset-3v3-timeout : Specify drive
+  strength used as a fallback in case the automatic calibration times
+  out on a 3.3 V signaling mode.
+- nvidia,pad-autocal-pull-up-offset-1v8-timeout,
+  nvidia,pad-autocal-pull-down-offset-1v8-timeout : Specify drive
+  strength used as a fallback in case the automatic calibration times
+  out on a 1.8 V signaling mode.
+- nvidia,pad-autocal-pull-up-offset-sdr104,
+  nvidia,pad-autocal-pull-down-offset-sdr104 : Specify drive strength
+  calibration offsets for SDR104 mode.
+- nvidia,pad-autocal-pull-up-offset-hs400,
+  nvidia,pad-autocal-pull-down-offset-hs400 : Specify drive strength
+  calibration offsets for HS400 mode.
+
+  Notes on the pad calibration pull up and pulldown offset values:
+    - The property values are drive codes which are programmed into the
+      PD_OFFSET and PU_OFFSET sections of the
+      SDHCI_TEGRA_AUTO_CAL_CONFIG register.
+    - A higher value corresponds to higher drive strength. Please refer
+      to the reference manual of the SoC for correct values.
+    - The SDR104 and HS400 timing specific values are used in
+      corresponding modes if specified.
 
 Example:
 sdhci@700b0000 {
@@ -60,5 +90,9 @@ sdhci@700b0000 {
 	pinctrl-names = "sdmmc-3v3", "sdmmc-1v8";
 	pinctrl-0 = <&sdmmc1_3v3>;
 	pinctrl-1 = <&sdmmc1_1v8>;
+	pad-autocal-pull-up-offset-3v3 = <0x00>;
+	pad-autocal-pull-down-offset-3v3 = <0x7d>;
+	pad-autocal-pull-up-offset-1v8 = <0x7b>;
+	pad-autocal-pull-down-offset-1v8 = <0x7b>;
 	status = "disabled";
 };
-- 
2.7.4

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

* [PATCH v2 05/10] dt-bindings: Add Tegra SDHCI pad pdpu offset bindings
@ 2018-07-26 12:26   ` Aapo Vienamo
  0 siblings, 0 replies; 29+ messages in thread
From: Aapo Vienamo @ 2018-07-26 12:26 UTC (permalink / raw)
  To: Ulf Hansson, Rob Herring, Mark Rutland, Thierry Reding,
	Jonathan Hunter, Adrian Hunter, Mikko Perttunen
  Cc: linux-mmc, devicetree, linux-tegra, linux-kernel, Aapo Vienamo

Add bindings documentation for pad pull up and pull down offset values to be
programmed before executing automatic pad drive strength calibration.

Signed-off-by: Aapo Vienamo <avienamo@nvidia.com>
---
 .../bindings/mmc/nvidia,tegra20-sdhci.txt          | 34 ++++++++++++++++++++++
 1 file changed, 34 insertions(+)

diff --git a/Documentation/devicetree/bindings/mmc/nvidia,tegra20-sdhci.txt b/Documentation/devicetree/bindings/mmc/nvidia,tegra20-sdhci.txt
index 95010cf..c3d8a15 100644
--- a/Documentation/devicetree/bindings/mmc/nvidia,tegra20-sdhci.txt
+++ b/Documentation/devicetree/bindings/mmc/nvidia,tegra20-sdhci.txt
@@ -24,6 +24,7 @@ Required properties:
 Optional properties:
 - power-gpios : Specify GPIOs for power control
 
+Optional properties for Tegra210 and Tegra186:
 Example:
 
 sdhci@c8000200 {
@@ -47,6 +48,35 @@ Optional properties for Tegra210 and Tegra186:
   pinctrl-1.
 - nvidia,only-1-8-v : The presence of this property indicates that the
   controller operates at a 1.8 V fixed I/O voltage.
+- nvidia,pad-autocal-pull-up-offset-3v3,
+  nvidia,pad-autocal-pull-down-offset-3v3 : Specify drive strength
+  calibration offsets for 3.3 V signaling modes.
+- nvidia,pad-autocal-pull-up-offset-1v8,
+  nvidia,pad-autocal-pull-down-offset-1v8 : Specify drive strength
+  calibration offsets for 1.8 V signaling modes.
+- nvidia,pad-autocal-pull-up-offset-3v3-timeout,
+  nvidia,pad-autocal-pull-down-offset-3v3-timeout : Specify drive
+  strength used as a fallback in case the automatic calibration times
+  out on a 3.3 V signaling mode.
+- nvidia,pad-autocal-pull-up-offset-1v8-timeout,
+  nvidia,pad-autocal-pull-down-offset-1v8-timeout : Specify drive
+  strength used as a fallback in case the automatic calibration times
+  out on a 1.8 V signaling mode.
+- nvidia,pad-autocal-pull-up-offset-sdr104,
+  nvidia,pad-autocal-pull-down-offset-sdr104 : Specify drive strength
+  calibration offsets for SDR104 mode.
+- nvidia,pad-autocal-pull-up-offset-hs400,
+  nvidia,pad-autocal-pull-down-offset-hs400 : Specify drive strength
+  calibration offsets for HS400 mode.
+
+  Notes on the pad calibration pull up and pulldown offset values:
+    - The property values are drive codes which are programmed into the
+      PD_OFFSET and PU_OFFSET sections of the
+      SDHCI_TEGRA_AUTO_CAL_CONFIG register.
+    - A higher value corresponds to higher drive strength. Please refer
+      to the reference manual of the SoC for correct values.
+    - The SDR104 and HS400 timing specific values are used in
+      corresponding modes if specified.
 
 Example:
 sdhci@700b0000 {
@@ -60,5 +90,9 @@ sdhci@700b0000 {
 	pinctrl-names = "sdmmc-3v3", "sdmmc-1v8";
 	pinctrl-0 = <&sdmmc1_3v3>;
 	pinctrl-1 = <&sdmmc1_1v8>;
+	pad-autocal-pull-up-offset-3v3 = <0x00>;
+	pad-autocal-pull-down-offset-3v3 = <0x7d>;
+	pad-autocal-pull-up-offset-1v8 = <0x7b>;
+	pad-autocal-pull-down-offset-1v8 = <0x7b>;
 	status = "disabled";
 };
-- 
2.7.4


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

* [PATCH v2 06/10] mmc: tegra: Program pad autocal offsets from dt
  2018-07-26 12:26 ` Aapo Vienamo
@ 2018-07-26 12:26   ` Aapo Vienamo
  -1 siblings, 0 replies; 29+ messages in thread
From: Aapo Vienamo @ 2018-07-26 12:26 UTC (permalink / raw)
  To: Ulf Hansson, Rob Herring, Mark Rutland, Thierry Reding,
	Jonathan Hunter, Adrian Hunter, Mikko Perttunen
  Cc: linux-mmc, devicetree, linux-tegra, linux-kernel, Aapo Vienamo

Parse the pad drive strength calibration offsets from the device tree.
Program the calibration offsets in accordance with the current signaling
mode.

Signed-off-by: Aapo Vienamo <avienamo@nvidia.com>
---
 drivers/mmc/host/sdhci-tegra.c | 152 ++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 151 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c
index 79ecdd0..295ae7a 100644
--- a/drivers/mmc/host/sdhci-tegra.c
+++ b/drivers/mmc/host/sdhci-tegra.c
@@ -49,6 +49,7 @@
 #define SDHCI_TEGRA_AUTO_CAL_CONFIG			0x1e4
 #define SDHCI_AUTO_CAL_START				BIT(31)
 #define SDHCI_AUTO_CAL_ENABLE				BIT(29)
+#define SDHCI_AUTO_CAL_PDPU_OFFSET_MASK			0x0000ffff
 
 #define SDHCI_TEGRA_SDMEM_COMP_PADCTRL			0x1e0
 #define SDHCI_TEGRA_SDMEM_COMP_PADCTRL_VREF_SEL_MASK	0x0000000f
@@ -72,6 +73,22 @@ struct sdhci_tegra_soc_data {
 	u32 nvquirks;
 };
 
+/* Magic pull up and pull down pad calibration offsets */
+struct sdhci_tegra_autocal_offsets {
+	u32 pull_up_3v3;
+	u32 pull_down_3v3;
+	u32 pull_up_3v3_timeout;
+	u32 pull_down_3v3_timeout;
+	u32 pull_up_1v8;
+	u32 pull_down_1v8;
+	u32 pull_up_1v8_timeout;
+	u32 pull_down_1v8_timeout;
+	u32 pull_up_sdr104;
+	u32 pull_down_sdr104;
+	u32 pull_up_hs400;
+	u32 pull_down_hs400;
+};
+
 struct sdhci_tegra {
 	const struct sdhci_tegra_soc_data *soc_data;
 	struct gpio_desc *power_gpio;
@@ -84,6 +101,8 @@ struct sdhci_tegra {
 	struct pinctrl *pinctrl_sdmmc;
 	struct pinctrl_state *pinctrl_state_3v3;
 	struct pinctrl_state *pinctrl_state_1v8;
+
+	struct sdhci_tegra_autocal_offsets autocal_offsets;
 };
 
 static u16 tegra_sdhci_readw(struct sdhci_host *host, int reg)
@@ -280,12 +299,45 @@ static bool tegra_sdhci_configure_card_clk(struct sdhci_host *host, bool enable)
 	return orig_enabled;
 }
 
+static void tegra_sdhci_set_pad_autocal_offset(struct sdhci_host *host,
+					       u16 pdpu)
+{
+	u32 reg;
+
+	reg = sdhci_readl(host, SDHCI_TEGRA_AUTO_CAL_CONFIG);
+	reg &= ~SDHCI_AUTO_CAL_PDPU_OFFSET_MASK;
+	reg |= pdpu;
+	sdhci_writel(host, reg, SDHCI_TEGRA_AUTO_CAL_CONFIG);
+}
+
 static void tegra_sdhci_pad_autocalib(struct sdhci_host *host)
 {
+	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+	struct sdhci_tegra *tegra_host = sdhci_pltfm_priv(pltfm_host);
+	struct sdhci_tegra_autocal_offsets offsets =
+			tegra_host->autocal_offsets;
+	struct mmc_ios *ios = &host->mmc->ios;
 	bool card_clk_enabled;
+	u16 pdpu;
 	u32 reg;
 	int ret;
 
+	switch (ios->timing) {
+	case MMC_TIMING_UHS_SDR104:
+		pdpu = offsets.pull_down_sdr104 << 8 | offsets.pull_up_sdr104;
+		break;
+	case MMC_TIMING_MMC_HS400:
+		pdpu = offsets.pull_down_hs400 << 8 | offsets.pull_up_hs400;
+		break;
+	default:
+		if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_180)
+			pdpu = offsets.pull_down_1v8 << 8 | offsets.pull_up_1v8;
+		else
+			pdpu = offsets.pull_down_3v3 << 8 | offsets.pull_up_3v3;
+	}
+
+	tegra_sdhci_set_pad_autocal_offset(host, pdpu);
+
 	card_clk_enabled = tegra_sdhci_configure_card_clk(host, false);
 
 	tegra_sdhci_configure_cal_pad(host, true);
@@ -303,8 +355,104 @@ static void tegra_sdhci_pad_autocalib(struct sdhci_host *host)
 
 	tegra_sdhci_configure_card_clk(host, card_clk_enabled);
 
-	if (ret)
+	if (ret) {
 		dev_err(mmc_dev(host->mmc), "Pad autocal timed out\n");
+
+		if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_180)
+			pdpu = offsets.pull_down_1v8_timeout << 8 |
+			       offsets.pull_up_1v8_timeout;
+		else
+			pdpu = offsets.pull_down_3v3_timeout << 8 |
+			       offsets.pull_up_3v3_timeout;
+
+		/* Disable automatic calibration and use fixed offsets */
+		reg = sdhci_readl(host, SDHCI_TEGRA_AUTO_CAL_CONFIG);
+		reg &= ~SDHCI_AUTO_CAL_ENABLE;
+		sdhci_writel(host, reg, SDHCI_TEGRA_AUTO_CAL_CONFIG);
+
+		tegra_sdhci_set_pad_autocal_offset(host, pdpu);
+	}
+}
+
+static void tegra_sdhci_parse_pad_autocal_dt(struct sdhci_host *host)
+{
+	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+	struct sdhci_tegra *tegra_host = sdhci_pltfm_priv(pltfm_host);
+	struct sdhci_tegra_autocal_offsets *autocal =
+			&tegra_host->autocal_offsets;
+	int err;
+
+	err = device_property_read_u32(host->mmc->parent,
+			"nvidia,pad-autocal-pull-up-offset-3v3",
+			&autocal->pull_up_3v3);
+	if (err)
+		autocal->pull_up_3v3 = 0;
+
+	err = device_property_read_u32(host->mmc->parent,
+			"nvidia,pad-autocal-pull-down-offset-3v3",
+			&autocal->pull_down_3v3);
+	if (err)
+		autocal->pull_down_3v3 = 0;
+
+	err = device_property_read_u32(host->mmc->parent,
+			"nvidia,pad-autocal-pull-up-offset-1v8",
+			&autocal->pull_up_1v8);
+	if (err)
+		autocal->pull_up_1v8 = 0;
+
+	err = device_property_read_u32(host->mmc->parent,
+			"nvidia,pad-autocal-pull-down-offset-1v8",
+			&autocal->pull_down_1v8);
+	if (err)
+		autocal->pull_down_1v8 = 0;
+
+	err = device_property_read_u32(host->mmc->parent,
+			"nvidia,pad-autocal-pull-up-offset-3v3-timeout",
+			&autocal->pull_up_3v3);
+	if (err)
+		autocal->pull_up_3v3_timeout = 0;
+
+	err = device_property_read_u32(host->mmc->parent,
+			"nvidia,pad-autocal-pull-down-offset-3v3-timeout",
+			&autocal->pull_down_3v3);
+	if (err)
+		autocal->pull_down_3v3_timeout = 0;
+
+	err = device_property_read_u32(host->mmc->parent,
+			"nvidia,pad-autocal-pull-up-offset-1v8-timeout",
+			&autocal->pull_up_1v8);
+	if (err)
+		autocal->pull_up_1v8_timeout = 0;
+
+	err = device_property_read_u32(host->mmc->parent,
+			"nvidia,pad-autocal-pull-down-offset-1v8-timeout",
+			&autocal->pull_down_1v8);
+	if (err)
+		autocal->pull_down_1v8_timeout = 0;
+
+	err = device_property_read_u32(host->mmc->parent,
+			"nvidia,pad-autocal-pull-up-offset-sdr104",
+			&autocal->pull_up_sdr104);
+	if (err)
+		autocal->pull_up_sdr104 = autocal->pull_up_1v8;
+
+	err = device_property_read_u32(host->mmc->parent,
+			"nvidia,pad-autocal-pull-down-offset-sdr104",
+			&autocal->pull_down_sdr104);
+	if (err)
+		autocal->pull_down_sdr104 = autocal->pull_down_1v8;
+
+	err = device_property_read_u32(host->mmc->parent,
+			"nvidia,pad-autocal-pull-up-offset-hs400",
+			&autocal->pull_up_hs400);
+	if (err)
+		autocal->pull_up_hs400 = autocal->pull_up_1v8;
+
+	err = device_property_read_u32(host->mmc->parent,
+			"nvidia,pad-autocal-pull-down-offset-hs400",
+			&autocal->pull_down_hs400);
+	if (err)
+		autocal->pull_down_hs400 = autocal->pull_down_1v8;
 }
 
 static void tegra_sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
@@ -670,6 +818,8 @@ static int sdhci_tegra_probe(struct platform_device *pdev)
 	if (tegra_host->soc_data->nvquirks & NVQUIRK_ENABLE_DDR50)
 		host->mmc->caps |= MMC_CAP_1_8V_DDR;
 
+	tegra_sdhci_parse_pad_autocal_dt(host);
+
 	tegra_host->power_gpio = devm_gpiod_get_optional(&pdev->dev, "power",
 							 GPIOD_OUT_HIGH);
 	if (IS_ERR(tegra_host->power_gpio)) {
-- 
2.7.4

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

* [PATCH v2 06/10] mmc: tegra: Program pad autocal offsets from dt
@ 2018-07-26 12:26   ` Aapo Vienamo
  0 siblings, 0 replies; 29+ messages in thread
From: Aapo Vienamo @ 2018-07-26 12:26 UTC (permalink / raw)
  To: Ulf Hansson, Rob Herring, Mark Rutland, Thierry Reding,
	Jonathan Hunter, Adrian Hunter, Mikko Perttunen
  Cc: linux-mmc, devicetree, linux-tegra, linux-kernel, Aapo Vienamo

Parse the pad drive strength calibration offsets from the device tree.
Program the calibration offsets in accordance with the current signaling
mode.

Signed-off-by: Aapo Vienamo <avienamo@nvidia.com>
---
 drivers/mmc/host/sdhci-tegra.c | 152 ++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 151 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c
index 79ecdd0..295ae7a 100644
--- a/drivers/mmc/host/sdhci-tegra.c
+++ b/drivers/mmc/host/sdhci-tegra.c
@@ -49,6 +49,7 @@
 #define SDHCI_TEGRA_AUTO_CAL_CONFIG			0x1e4
 #define SDHCI_AUTO_CAL_START				BIT(31)
 #define SDHCI_AUTO_CAL_ENABLE				BIT(29)
+#define SDHCI_AUTO_CAL_PDPU_OFFSET_MASK			0x0000ffff
 
 #define SDHCI_TEGRA_SDMEM_COMP_PADCTRL			0x1e0
 #define SDHCI_TEGRA_SDMEM_COMP_PADCTRL_VREF_SEL_MASK	0x0000000f
@@ -72,6 +73,22 @@ struct sdhci_tegra_soc_data {
 	u32 nvquirks;
 };
 
+/* Magic pull up and pull down pad calibration offsets */
+struct sdhci_tegra_autocal_offsets {
+	u32 pull_up_3v3;
+	u32 pull_down_3v3;
+	u32 pull_up_3v3_timeout;
+	u32 pull_down_3v3_timeout;
+	u32 pull_up_1v8;
+	u32 pull_down_1v8;
+	u32 pull_up_1v8_timeout;
+	u32 pull_down_1v8_timeout;
+	u32 pull_up_sdr104;
+	u32 pull_down_sdr104;
+	u32 pull_up_hs400;
+	u32 pull_down_hs400;
+};
+
 struct sdhci_tegra {
 	const struct sdhci_tegra_soc_data *soc_data;
 	struct gpio_desc *power_gpio;
@@ -84,6 +101,8 @@ struct sdhci_tegra {
 	struct pinctrl *pinctrl_sdmmc;
 	struct pinctrl_state *pinctrl_state_3v3;
 	struct pinctrl_state *pinctrl_state_1v8;
+
+	struct sdhci_tegra_autocal_offsets autocal_offsets;
 };
 
 static u16 tegra_sdhci_readw(struct sdhci_host *host, int reg)
@@ -280,12 +299,45 @@ static bool tegra_sdhci_configure_card_clk(struct sdhci_host *host, bool enable)
 	return orig_enabled;
 }
 
+static void tegra_sdhci_set_pad_autocal_offset(struct sdhci_host *host,
+					       u16 pdpu)
+{
+	u32 reg;
+
+	reg = sdhci_readl(host, SDHCI_TEGRA_AUTO_CAL_CONFIG);
+	reg &= ~SDHCI_AUTO_CAL_PDPU_OFFSET_MASK;
+	reg |= pdpu;
+	sdhci_writel(host, reg, SDHCI_TEGRA_AUTO_CAL_CONFIG);
+}
+
 static void tegra_sdhci_pad_autocalib(struct sdhci_host *host)
 {
+	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+	struct sdhci_tegra *tegra_host = sdhci_pltfm_priv(pltfm_host);
+	struct sdhci_tegra_autocal_offsets offsets =
+			tegra_host->autocal_offsets;
+	struct mmc_ios *ios = &host->mmc->ios;
 	bool card_clk_enabled;
+	u16 pdpu;
 	u32 reg;
 	int ret;
 
+	switch (ios->timing) {
+	case MMC_TIMING_UHS_SDR104:
+		pdpu = offsets.pull_down_sdr104 << 8 | offsets.pull_up_sdr104;
+		break;
+	case MMC_TIMING_MMC_HS400:
+		pdpu = offsets.pull_down_hs400 << 8 | offsets.pull_up_hs400;
+		break;
+	default:
+		if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_180)
+			pdpu = offsets.pull_down_1v8 << 8 | offsets.pull_up_1v8;
+		else
+			pdpu = offsets.pull_down_3v3 << 8 | offsets.pull_up_3v3;
+	}
+
+	tegra_sdhci_set_pad_autocal_offset(host, pdpu);
+
 	card_clk_enabled = tegra_sdhci_configure_card_clk(host, false);
 
 	tegra_sdhci_configure_cal_pad(host, true);
@@ -303,8 +355,104 @@ static void tegra_sdhci_pad_autocalib(struct sdhci_host *host)
 
 	tegra_sdhci_configure_card_clk(host, card_clk_enabled);
 
-	if (ret)
+	if (ret) {
 		dev_err(mmc_dev(host->mmc), "Pad autocal timed out\n");
+
+		if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_180)
+			pdpu = offsets.pull_down_1v8_timeout << 8 |
+			       offsets.pull_up_1v8_timeout;
+		else
+			pdpu = offsets.pull_down_3v3_timeout << 8 |
+			       offsets.pull_up_3v3_timeout;
+
+		/* Disable automatic calibration and use fixed offsets */
+		reg = sdhci_readl(host, SDHCI_TEGRA_AUTO_CAL_CONFIG);
+		reg &= ~SDHCI_AUTO_CAL_ENABLE;
+		sdhci_writel(host, reg, SDHCI_TEGRA_AUTO_CAL_CONFIG);
+
+		tegra_sdhci_set_pad_autocal_offset(host, pdpu);
+	}
+}
+
+static void tegra_sdhci_parse_pad_autocal_dt(struct sdhci_host *host)
+{
+	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+	struct sdhci_tegra *tegra_host = sdhci_pltfm_priv(pltfm_host);
+	struct sdhci_tegra_autocal_offsets *autocal =
+			&tegra_host->autocal_offsets;
+	int err;
+
+	err = device_property_read_u32(host->mmc->parent,
+			"nvidia,pad-autocal-pull-up-offset-3v3",
+			&autocal->pull_up_3v3);
+	if (err)
+		autocal->pull_up_3v3 = 0;
+
+	err = device_property_read_u32(host->mmc->parent,
+			"nvidia,pad-autocal-pull-down-offset-3v3",
+			&autocal->pull_down_3v3);
+	if (err)
+		autocal->pull_down_3v3 = 0;
+
+	err = device_property_read_u32(host->mmc->parent,
+			"nvidia,pad-autocal-pull-up-offset-1v8",
+			&autocal->pull_up_1v8);
+	if (err)
+		autocal->pull_up_1v8 = 0;
+
+	err = device_property_read_u32(host->mmc->parent,
+			"nvidia,pad-autocal-pull-down-offset-1v8",
+			&autocal->pull_down_1v8);
+	if (err)
+		autocal->pull_down_1v8 = 0;
+
+	err = device_property_read_u32(host->mmc->parent,
+			"nvidia,pad-autocal-pull-up-offset-3v3-timeout",
+			&autocal->pull_up_3v3);
+	if (err)
+		autocal->pull_up_3v3_timeout = 0;
+
+	err = device_property_read_u32(host->mmc->parent,
+			"nvidia,pad-autocal-pull-down-offset-3v3-timeout",
+			&autocal->pull_down_3v3);
+	if (err)
+		autocal->pull_down_3v3_timeout = 0;
+
+	err = device_property_read_u32(host->mmc->parent,
+			"nvidia,pad-autocal-pull-up-offset-1v8-timeout",
+			&autocal->pull_up_1v8);
+	if (err)
+		autocal->pull_up_1v8_timeout = 0;
+
+	err = device_property_read_u32(host->mmc->parent,
+			"nvidia,pad-autocal-pull-down-offset-1v8-timeout",
+			&autocal->pull_down_1v8);
+	if (err)
+		autocal->pull_down_1v8_timeout = 0;
+
+	err = device_property_read_u32(host->mmc->parent,
+			"nvidia,pad-autocal-pull-up-offset-sdr104",
+			&autocal->pull_up_sdr104);
+	if (err)
+		autocal->pull_up_sdr104 = autocal->pull_up_1v8;
+
+	err = device_property_read_u32(host->mmc->parent,
+			"nvidia,pad-autocal-pull-down-offset-sdr104",
+			&autocal->pull_down_sdr104);
+	if (err)
+		autocal->pull_down_sdr104 = autocal->pull_down_1v8;
+
+	err = device_property_read_u32(host->mmc->parent,
+			"nvidia,pad-autocal-pull-up-offset-hs400",
+			&autocal->pull_up_hs400);
+	if (err)
+		autocal->pull_up_hs400 = autocal->pull_up_1v8;
+
+	err = device_property_read_u32(host->mmc->parent,
+			"nvidia,pad-autocal-pull-down-offset-hs400",
+			&autocal->pull_down_hs400);
+	if (err)
+		autocal->pull_down_hs400 = autocal->pull_down_1v8;
 }
 
 static void tegra_sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
@@ -670,6 +818,8 @@ static int sdhci_tegra_probe(struct platform_device *pdev)
 	if (tegra_host->soc_data->nvquirks & NVQUIRK_ENABLE_DDR50)
 		host->mmc->caps |= MMC_CAP_1_8V_DDR;
 
+	tegra_sdhci_parse_pad_autocal_dt(host);
+
 	tegra_host->power_gpio = devm_gpiod_get_optional(&pdev->dev, "power",
 							 GPIOD_OUT_HIGH);
 	if (IS_ERR(tegra_host->power_gpio)) {
-- 
2.7.4


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

* [PATCH v2 07/10] arm64: dts: tegra186: Add sdmmc pad auto calibration offsets
  2018-07-26 12:26 ` Aapo Vienamo
@ 2018-07-26 12:26   ` Aapo Vienamo
  -1 siblings, 0 replies; 29+ messages in thread
From: Aapo Vienamo @ 2018-07-26 12:26 UTC (permalink / raw)
  To: Ulf Hansson, Rob Herring, Mark Rutland, Thierry Reding,
	Jonathan Hunter, Adrian Hunter, Mikko Perttunen
  Cc: linux-mmc, devicetree, linux-tegra, linux-kernel, Aapo Vienamo

Add the calibration offset properties used for automatic pad drive
strength calibration.

Signed-off-by: Aapo Vienamo <avienamo@nvidia.com>
---
 arch/arm64/boot/dts/nvidia/tegra186.dtsi | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/arch/arm64/boot/dts/nvidia/tegra186.dtsi b/arch/arm64/boot/dts/nvidia/tegra186.dtsi
index fc14dd3..1c5535b 100644
--- a/arch/arm64/boot/dts/nvidia/tegra186.dtsi
+++ b/arch/arm64/boot/dts/nvidia/tegra186.dtsi
@@ -240,6 +240,12 @@
 		pinctrl-names = "sdmmc-3v3", "sdmmc-1v8";
 		pinctrl-0 = <&sdmmc1_3v3>;
 		pinctrl-1 = <&sdmmc1_1v8>;
+		pad-autocal-pull-up-offset-3v3-timeout = <0x07>;
+		pad-autocal-pull-down-offset-3v3-timeout = <0x06>;
+		pad-autocal-pull-up-offset-1v8-timeout = <0x07>;
+		pad-autocal-pull-down-offset-1v8-timeout = <0x07>;
+		pad-autocal-pull-up-offset-sdr104 = <0x03>;
+		pad-autocal-pull-down-offset-sdr104 = <0x05>;
 		status = "disabled";
 	};
 
@@ -254,6 +260,10 @@
 		pinctrl-names = "sdmmc-3v3", "sdmmc-1v8";
 		pinctrl-0 = <&sdmmc2_3v3>;
 		pinctrl-1 = <&sdmmc2_1v8>;
+		pad-autocal-pull-up-offset-3v3-timeout = <0x07>;
+		pad-autocal-pull-down-offset-3v3-timeout = <0x06>;
+		pad-autocal-pull-up-offset-1v8-timeout = <0x07>;
+		pad-autocal-pull-down-offset-1v8-timeout = <0x07>;
 		status = "disabled";
 	};
 
@@ -268,6 +278,12 @@
 		pinctrl-names = "sdmmc-3v3", "sdmmc-1v8";
 		pinctrl-0 = <&sdmmc3_3v3>;
 		pinctrl-1 = <&sdmmc3_1v8>;
+		pad-autocal-pull-up-offset-1v8 = <0x00>;
+		pad-autocal-pull-down-offset-1v8 = <0x7a>;
+		pad-autocal-pull-up-offset-3v3-timeout = <0x07>;
+		pad-autocal-pull-down-offset-3v3-timeout = <0x06>;
+		pad-autocal-pull-up-offset-1v8-timeout = <0x07>;
+		pad-autocal-pull-down-offset-1v8-timeout = <0x07>;
 		status = "disabled";
 	};
 
@@ -280,6 +296,10 @@
 		resets = <&bpmp TEGRA186_RESET_SDMMC4>;
 		reset-names = "sdhci";
 		nvidia,only-1-8-v;
+		pad-autocal-pull-up-offset-hs400 = <0x05>;
+		pad-autocal-pull-down-offset-hs400 = <0x05>;
+		pad-autocal-pull-up-offset-1v8-timeout = <0x0a>;
+		pad-autocal-pull-down-offset-1v8-timeout = <0x0a>;
 		status = "disabled";
 	};
 
-- 
2.7.4

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

* [PATCH v2 07/10] arm64: dts: tegra186: Add sdmmc pad auto calibration offsets
@ 2018-07-26 12:26   ` Aapo Vienamo
  0 siblings, 0 replies; 29+ messages in thread
From: Aapo Vienamo @ 2018-07-26 12:26 UTC (permalink / raw)
  To: Ulf Hansson, Rob Herring, Mark Rutland, Thierry Reding,
	Jonathan Hunter, Adrian Hunter, Mikko Perttunen
  Cc: linux-mmc, devicetree, linux-tegra, linux-kernel, Aapo Vienamo

Add the calibration offset properties used for automatic pad drive
strength calibration.

Signed-off-by: Aapo Vienamo <avienamo@nvidia.com>
---
 arch/arm64/boot/dts/nvidia/tegra186.dtsi | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/arch/arm64/boot/dts/nvidia/tegra186.dtsi b/arch/arm64/boot/dts/nvidia/tegra186.dtsi
index fc14dd3..1c5535b 100644
--- a/arch/arm64/boot/dts/nvidia/tegra186.dtsi
+++ b/arch/arm64/boot/dts/nvidia/tegra186.dtsi
@@ -240,6 +240,12 @@
 		pinctrl-names = "sdmmc-3v3", "sdmmc-1v8";
 		pinctrl-0 = <&sdmmc1_3v3>;
 		pinctrl-1 = <&sdmmc1_1v8>;
+		pad-autocal-pull-up-offset-3v3-timeout = <0x07>;
+		pad-autocal-pull-down-offset-3v3-timeout = <0x06>;
+		pad-autocal-pull-up-offset-1v8-timeout = <0x07>;
+		pad-autocal-pull-down-offset-1v8-timeout = <0x07>;
+		pad-autocal-pull-up-offset-sdr104 = <0x03>;
+		pad-autocal-pull-down-offset-sdr104 = <0x05>;
 		status = "disabled";
 	};
 
@@ -254,6 +260,10 @@
 		pinctrl-names = "sdmmc-3v3", "sdmmc-1v8";
 		pinctrl-0 = <&sdmmc2_3v3>;
 		pinctrl-1 = <&sdmmc2_1v8>;
+		pad-autocal-pull-up-offset-3v3-timeout = <0x07>;
+		pad-autocal-pull-down-offset-3v3-timeout = <0x06>;
+		pad-autocal-pull-up-offset-1v8-timeout = <0x07>;
+		pad-autocal-pull-down-offset-1v8-timeout = <0x07>;
 		status = "disabled";
 	};
 
@@ -268,6 +278,12 @@
 		pinctrl-names = "sdmmc-3v3", "sdmmc-1v8";
 		pinctrl-0 = <&sdmmc3_3v3>;
 		pinctrl-1 = <&sdmmc3_1v8>;
+		pad-autocal-pull-up-offset-1v8 = <0x00>;
+		pad-autocal-pull-down-offset-1v8 = <0x7a>;
+		pad-autocal-pull-up-offset-3v3-timeout = <0x07>;
+		pad-autocal-pull-down-offset-3v3-timeout = <0x06>;
+		pad-autocal-pull-up-offset-1v8-timeout = <0x07>;
+		pad-autocal-pull-down-offset-1v8-timeout = <0x07>;
 		status = "disabled";
 	};
 
@@ -280,6 +296,10 @@
 		resets = <&bpmp TEGRA186_RESET_SDMMC4>;
 		reset-names = "sdhci";
 		nvidia,only-1-8-v;
+		pad-autocal-pull-up-offset-hs400 = <0x05>;
+		pad-autocal-pull-down-offset-hs400 = <0x05>;
+		pad-autocal-pull-up-offset-1v8-timeout = <0x0a>;
+		pad-autocal-pull-down-offset-1v8-timeout = <0x0a>;
 		status = "disabled";
 	};
 
-- 
2.7.4


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

* [PATCH v2 08/10] arm64: dts: tegra210: Add sdmmc pad auto calibration offsets
  2018-07-26 12:26 ` Aapo Vienamo
@ 2018-07-26 12:26   ` Aapo Vienamo
  -1 siblings, 0 replies; 29+ messages in thread
From: Aapo Vienamo @ 2018-07-26 12:26 UTC (permalink / raw)
  To: Ulf Hansson, Rob Herring, Mark Rutland, Thierry Reding,
	Jonathan Hunter, Adrian Hunter, Mikko Perttunen
  Cc: linux-mmc, devicetree, linux-tegra, linux-kernel, Aapo Vienamo

Add the calibration offset properties used for automatic pad drive
strength calibration.

Signed-off-by: Aapo Vienamo <avienamo@nvidia.com>
---
 arch/arm64/boot/dts/nvidia/tegra210.dtsi | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/arch/arm64/boot/dts/nvidia/tegra210.dtsi b/arch/arm64/boot/dts/nvidia/tegra210.dtsi
index c449566..c16ab5f 100644
--- a/arch/arm64/boot/dts/nvidia/tegra210.dtsi
+++ b/arch/arm64/boot/dts/nvidia/tegra210.dtsi
@@ -1051,6 +1051,10 @@
 		pinctrl-names = "sdmmc-3v3", "sdmmc-1v8";
 		pinctrl-0 = <&sdmmc1_3v3>;
 		pinctrl-1 = <&sdmmc1_1v8>;
+		pad-autocal-pull-up-offset-3v3 = <0x00>;
+		pad-autocal-pull-down-offset-3v3 = <0x7d>;
+		pad-autocal-pull-up-offset-1v8 = <0x7b>;
+		pad-autocal-pull-down-offset-1v8 = <0x7b>;
 		status = "disabled";
 	};
 
@@ -1062,6 +1066,8 @@
 		clock-names = "sdhci";
 		resets = <&tegra_car 9>;
 		reset-names = "sdhci";
+		pad-autocal-pull-up-offset-1v8 = <0x05>;
+		pad-autocal-pull-down-offset-1v8 = <0x05>;
 		status = "disabled";
 	};
 
@@ -1076,6 +1082,10 @@
 		pinctrl-names = "sdmmc-3v3", "sdmmc-1v8";
 		pinctrl-0 = <&sdmmc3_3v3>;
 		pinctrl-1 = <&sdmmc3_1v8>;
+		pad-autocal-pull-up-offset-3v3 = <0x00>;
+		pad-autocal-pull-down-offset-3v3 = <0x7d>;
+		pad-autocal-pull-up-offset-1v8 = <0x7b>;
+		pad-autocal-pull-down-offset-1v8 = <0x7b>;
 		status = "disabled";
 	};
 
@@ -1088,6 +1098,8 @@
 		resets = <&tegra_car 15>;
 		reset-names = "sdhci";
 		nvidia,only-1-8-v;
+		pad-autocal-pull-up-offset-1v8 = <0x05>;
+		pad-autocal-pull-down-offset-1v8 = <0x05>;
 		status = "disabled";
 	};
 
-- 
2.7.4

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

* [PATCH v2 08/10] arm64: dts: tegra210: Add sdmmc pad auto calibration offsets
@ 2018-07-26 12:26   ` Aapo Vienamo
  0 siblings, 0 replies; 29+ messages in thread
From: Aapo Vienamo @ 2018-07-26 12:26 UTC (permalink / raw)
  To: Ulf Hansson, Rob Herring, Mark Rutland, Thierry Reding,
	Jonathan Hunter, Adrian Hunter, Mikko Perttunen
  Cc: linux-mmc, devicetree, linux-tegra, linux-kernel, Aapo Vienamo

Add the calibration offset properties used for automatic pad drive
strength calibration.

Signed-off-by: Aapo Vienamo <avienamo@nvidia.com>
---
 arch/arm64/boot/dts/nvidia/tegra210.dtsi | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/arch/arm64/boot/dts/nvidia/tegra210.dtsi b/arch/arm64/boot/dts/nvidia/tegra210.dtsi
index c449566..c16ab5f 100644
--- a/arch/arm64/boot/dts/nvidia/tegra210.dtsi
+++ b/arch/arm64/boot/dts/nvidia/tegra210.dtsi
@@ -1051,6 +1051,10 @@
 		pinctrl-names = "sdmmc-3v3", "sdmmc-1v8";
 		pinctrl-0 = <&sdmmc1_3v3>;
 		pinctrl-1 = <&sdmmc1_1v8>;
+		pad-autocal-pull-up-offset-3v3 = <0x00>;
+		pad-autocal-pull-down-offset-3v3 = <0x7d>;
+		pad-autocal-pull-up-offset-1v8 = <0x7b>;
+		pad-autocal-pull-down-offset-1v8 = <0x7b>;
 		status = "disabled";
 	};
 
@@ -1062,6 +1066,8 @@
 		clock-names = "sdhci";
 		resets = <&tegra_car 9>;
 		reset-names = "sdhci";
+		pad-autocal-pull-up-offset-1v8 = <0x05>;
+		pad-autocal-pull-down-offset-1v8 = <0x05>;
 		status = "disabled";
 	};
 
@@ -1076,6 +1082,10 @@
 		pinctrl-names = "sdmmc-3v3", "sdmmc-1v8";
 		pinctrl-0 = <&sdmmc3_3v3>;
 		pinctrl-1 = <&sdmmc3_1v8>;
+		pad-autocal-pull-up-offset-3v3 = <0x00>;
+		pad-autocal-pull-down-offset-3v3 = <0x7d>;
+		pad-autocal-pull-up-offset-1v8 = <0x7b>;
+		pad-autocal-pull-down-offset-1v8 = <0x7b>;
 		status = "disabled";
 	};
 
@@ -1088,6 +1098,8 @@
 		resets = <&tegra_car 15>;
 		reset-names = "sdhci";
 		nvidia,only-1-8-v;
+		pad-autocal-pull-up-offset-1v8 = <0x05>;
+		pad-autocal-pull-down-offset-1v8 = <0x05>;
 		status = "disabled";
 	};
 
-- 
2.7.4


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

* [PATCH v2 09/10] mmc: tegra: Perform pad calibration after voltage switch
  2018-07-26 12:26 ` Aapo Vienamo
@ 2018-07-26 12:26   ` Aapo Vienamo
  -1 siblings, 0 replies; 29+ messages in thread
From: Aapo Vienamo @ 2018-07-26 12:26 UTC (permalink / raw)
  To: Ulf Hansson, Rob Herring, Mark Rutland, Thierry Reding,
	Jonathan Hunter, Adrian Hunter, Mikko Perttunen
  Cc: linux-mmc, devicetree, linux-tegra, linux-kernel, Aapo Vienamo

Run the automatic pad calibration after voltage switching if
tegra_host->pad_calib_required is set.

Signed-off-by: Aapo Vienamo <avienamo@nvidia.com>
---
 drivers/mmc/host/sdhci-tegra.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c
index 295ae7a..8c89f58 100644
--- a/drivers/mmc/host/sdhci-tegra.c
+++ b/drivers/mmc/host/sdhci-tegra.c
@@ -570,6 +570,8 @@ static int sdhci_tegra_start_signal_voltage_switch(struct mmc_host *mmc,
 						   struct mmc_ios *ios)
 {
 	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);
 	int ret = 0;
 
 	if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_330) {
@@ -584,6 +586,9 @@ static int sdhci_tegra_start_signal_voltage_switch(struct mmc_host *mmc,
 		ret = tegra_sdhci_set_padctrl(host, ios->signal_voltage);
 	}
 
+	if (tegra_host->pad_calib_required)
+		tegra_sdhci_pad_autocalib(host);
+
 	return ret;
 }
 
-- 
2.7.4

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

* [PATCH v2 09/10] mmc: tegra: Perform pad calibration after voltage switch
@ 2018-07-26 12:26   ` Aapo Vienamo
  0 siblings, 0 replies; 29+ messages in thread
From: Aapo Vienamo @ 2018-07-26 12:26 UTC (permalink / raw)
  To: Ulf Hansson, Rob Herring, Mark Rutland, Thierry Reding,
	Jonathan Hunter, Adrian Hunter, Mikko Perttunen
  Cc: linux-mmc, devicetree, linux-tegra, linux-kernel, Aapo Vienamo

Run the automatic pad calibration after voltage switching if
tegra_host->pad_calib_required is set.

Signed-off-by: Aapo Vienamo <avienamo@nvidia.com>
---
 drivers/mmc/host/sdhci-tegra.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c
index 295ae7a..8c89f58 100644
--- a/drivers/mmc/host/sdhci-tegra.c
+++ b/drivers/mmc/host/sdhci-tegra.c
@@ -570,6 +570,8 @@ static int sdhci_tegra_start_signal_voltage_switch(struct mmc_host *mmc,
 						   struct mmc_ios *ios)
 {
 	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);
 	int ret = 0;
 
 	if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_330) {
@@ -584,6 +586,9 @@ static int sdhci_tegra_start_signal_voltage_switch(struct mmc_host *mmc,
 		ret = tegra_sdhci_set_padctrl(host, ios->signal_voltage);
 	}
 
+	if (tegra_host->pad_calib_required)
+		tegra_sdhci_pad_autocalib(host);
+
 	return ret;
 }
 
-- 
2.7.4


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

* [PATCH v2 10/10] mmc: tegra: Enable pad calibration on Tegra210 and Tegra186
  2018-07-26 12:26 ` Aapo Vienamo
@ 2018-07-26 12:26   ` Aapo Vienamo
  -1 siblings, 0 replies; 29+ messages in thread
From: Aapo Vienamo @ 2018-07-26 12:26 UTC (permalink / raw)
  To: Ulf Hansson, Rob Herring, Mark Rutland, Thierry Reding,
	Jonathan Hunter, Adrian Hunter, Mikko Perttunen
  Cc: linux-mmc, devicetree, linux-tegra, linux-kernel, Aapo Vienamo

Set NVQUIRK_HAS_PADCALIB on Tegra210 and Tegra186 to enable automatic
pad drive strength calibration.

Signed-off-by: Aapo Vienamo <avienamo@nvidia.com>
---
 drivers/mmc/host/sdhci-tegra.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c
index 8c89f58..c587ae1 100644
--- a/drivers/mmc/host/sdhci-tegra.c
+++ b/drivers/mmc/host/sdhci-tegra.c
@@ -742,7 +742,8 @@ static const struct sdhci_pltfm_data sdhci_tegra210_pdata = {
 
 static const struct sdhci_tegra_soc_data soc_data_tegra210 = {
 	.pdata = &sdhci_tegra210_pdata,
-	.nvquirks = NVQUIRK_NEEDS_PAD_CONTROL,
+	.nvquirks = NVQUIRK_NEEDS_PAD_CONTROL |
+		    NVQUIRK_HAS_PADCALIB,
 };
 
 static const struct sdhci_pltfm_data sdhci_tegra186_pdata = {
@@ -766,7 +767,8 @@ static const struct sdhci_pltfm_data sdhci_tegra186_pdata = {
 
 static const struct sdhci_tegra_soc_data soc_data_tegra186 = {
 	.pdata = &sdhci_tegra186_pdata,
-	.nvquirks = NVQUIRK_NEEDS_PAD_CONTROL,
+	.nvquirks = NVQUIRK_NEEDS_PAD_CONTROL |
+		    NVQUIRK_HAS_PADCALIB,
 };
 
 static const struct of_device_id sdhci_tegra_dt_match[] = {
-- 
2.7.4

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

* [PATCH v2 10/10] mmc: tegra: Enable pad calibration on Tegra210 and Tegra186
@ 2018-07-26 12:26   ` Aapo Vienamo
  0 siblings, 0 replies; 29+ messages in thread
From: Aapo Vienamo @ 2018-07-26 12:26 UTC (permalink / raw)
  To: Ulf Hansson, Rob Herring, Mark Rutland, Thierry Reding,
	Jonathan Hunter, Adrian Hunter, Mikko Perttunen
  Cc: linux-mmc, devicetree, linux-tegra, linux-kernel, Aapo Vienamo

Set NVQUIRK_HAS_PADCALIB on Tegra210 and Tegra186 to enable automatic
pad drive strength calibration.

Signed-off-by: Aapo Vienamo <avienamo@nvidia.com>
---
 drivers/mmc/host/sdhci-tegra.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c
index 8c89f58..c587ae1 100644
--- a/drivers/mmc/host/sdhci-tegra.c
+++ b/drivers/mmc/host/sdhci-tegra.c
@@ -742,7 +742,8 @@ static const struct sdhci_pltfm_data sdhci_tegra210_pdata = {
 
 static const struct sdhci_tegra_soc_data soc_data_tegra210 = {
 	.pdata = &sdhci_tegra210_pdata,
-	.nvquirks = NVQUIRK_NEEDS_PAD_CONTROL,
+	.nvquirks = NVQUIRK_NEEDS_PAD_CONTROL |
+		    NVQUIRK_HAS_PADCALIB,
 };
 
 static const struct sdhci_pltfm_data sdhci_tegra186_pdata = {
@@ -766,7 +767,8 @@ static const struct sdhci_pltfm_data sdhci_tegra186_pdata = {
 
 static const struct sdhci_tegra_soc_data soc_data_tegra186 = {
 	.pdata = &sdhci_tegra186_pdata,
-	.nvquirks = NVQUIRK_NEEDS_PAD_CONTROL,
+	.nvquirks = NVQUIRK_NEEDS_PAD_CONTROL |
+		    NVQUIRK_HAS_PADCALIB,
 };
 
 static const struct of_device_id sdhci_tegra_dt_match[] = {
-- 
2.7.4


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

* Re: [PATCH v2 00/10] Tegra SDHCI update the pad autocal procedure
  2018-07-26 12:26 ` Aapo Vienamo
                   ` (10 preceding siblings ...)
  (?)
@ 2018-07-30 15:07 ` Ulf Hansson
  2018-07-30 15:43     ` Aapo Vienamo
  -1 siblings, 1 reply; 29+ messages in thread
From: Ulf Hansson @ 2018-07-30 15:07 UTC (permalink / raw)
  To: Aapo Vienamo
  Cc: Rob Herring, Mark Rutland, Thierry Reding, Jonathan Hunter,
	Adrian Hunter, Mikko Perttunen, linux-mmc, devicetree,
	linux-tegra, Linux Kernel Mailing List

On 26 July 2018 at 14:26, Aapo Vienamo <avienamo@nvidia.com> wrote:
> Hi all,
>
> Update the tegra_sdhci_pad_autocalib() pad drive strength calibration
> procedure to match the ones specified in the TRMs of the more recent
> SoCs. This was tested on Tegra186, Tegra210, and Tegra124, although it
> should not break things older generations either.
>
> This series depends on the "Tegra SDHCI enable 1.8 V signaling on
> Tegar210 and Tegra186" series posted earlier.

According to the cover letter of the above series, it states that it
depends on $subject series. A circular dependency. :-)

In fact, there should be no dependency at all or else there seems to
be a DT compatibility problem here...

Anyway, I think it actually makes sense to fold in all changes into
one series. Make sure the dt-doc changes comes first, then the driver
changes and finally arm64/dts changes. This should make it easy to
follow the review and I can pick the mmc parts and the soc maintainer
can pick the arm64/dts changes.

[...]

Kind regards
Uffe

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

* Re: [PATCH v2 00/10] Tegra SDHCI update the pad autocal procedure
  2018-07-30 15:07 ` [PATCH v2 00/10] Tegra SDHCI update the pad autocal procedure Ulf Hansson
  2018-07-30 15:43     ` Aapo Vienamo
@ 2018-07-30 15:43     ` Aapo Vienamo
  0 siblings, 0 replies; 29+ messages in thread
From: Aapo Vienamo @ 2018-07-30 15:43 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Rob Herring, Mark Rutland, Thierry Reding, Jonathan Hunter,
	Adrian Hunter, Mikko Perttunen, linux-mmc, devicetree,
	linux-tegra, Linux Kernel Mailing List

On Mon, 30 Jul 2018 17:07:59 +0200
Ulf Hansson <ulf.hansson@linaro.org> wrote:

> On 26 July 2018 at 14:26, Aapo Vienamo <avienamo@nvidia.com> wrote:
> > Hi all,
> >
> > Update the tegra_sdhci_pad_autocalib() pad drive strength calibration
> > procedure to match the ones specified in the TRMs of the more recent
> > SoCs. This was tested on Tegra186, Tegra210, and Tegra124, although it
> > should not break things older generations either.
> >
> > This series depends on the "Tegra SDHCI enable 1.8 V signaling on
> > Tegar210 and Tegra186" series posted earlier.  
> 
> According to the cover letter of the above series, it states that it
> depends on $subject series. A circular dependency. :-)

The dependency chain goes like this: "Tegra SDHCI update the pad
autocal procedure" -> "Tegra SDHCI enable 1.8 V signaling on Tegar210
and Tegra186" -> "Tegra PMC pinctrl pad configuration".

> In fact, there should be no dependency at all or else there seems to
> be a DT compatibility problem here...

From a functionality perspective there's no strict dependency, however,
I don't think "[PATCH v2 09/10] mmc: tegra: Perform pad calibration
after voltage switch" can be applied cleanly without
"[PATCH v2 03/10] mmc: tegra: Reconfigure pad voltages during voltage
switching" from the "Tegra SDHCI enable 1.8 V signaling on Tegar210 and
Tegra186" series.

> Anyway, I think it actually makes sense to fold in all changes into
> one series. Make sure the dt-doc changes comes first, then the driver
> changes and finally arm64/dts changes. This should make it easy to
> follow the review and I can pick the mmc parts and the soc maintainer
> can pick the arm64/dts changes.

I've sent the changes in multiple part because I've been working on
further changes to the driver while the previous parts have been
getting reviewed. This is still the case and there's still going to be
at least one more series which adds support for HS200 tuning and some
smaller changes after it. However, the HS200 work is probably going to
be ready for review in a day or two. I can send these as a one series
from now on, although at this point it would be 27 patches in total
and even more with the HS200 patches.

I can do that if you prefer to do it that way. Makes my life somewhat
easier too.

 -Aapo

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

* Re: [PATCH v2 00/10] Tegra SDHCI update the pad autocal procedure
@ 2018-07-30 15:43     ` Aapo Vienamo
  0 siblings, 0 replies; 29+ messages in thread
From: Aapo Vienamo @ 2018-07-30 15:43 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Rob Herring, Mark Rutland, Thierry Reding, Jonathan Hunter,
	Adrian Hunter, Mikko Perttunen, linux-mmc, devicetree,
	linux-tegra, Linux Kernel Mailing List

On Mon, 30 Jul 2018 17:07:59 +0200
Ulf Hansson <ulf.hansson@linaro.org> wrote:

> On 26 July 2018 at 14:26, Aapo Vienamo <avienamo@nvidia.com> wrote:
> > Hi all,
> >
> > Update the tegra_sdhci_pad_autocalib() pad drive strength calibration
> > procedure to match the ones specified in the TRMs of the more recent
> > SoCs. This was tested on Tegra186, Tegra210, and Tegra124, although it
> > should not break things older generations either.
> >
> > This series depends on the "Tegra SDHCI enable 1.8 V signaling on
> > Tegar210 and Tegra186" series posted earlier.  
> 
> According to the cover letter of the above series, it states that it
> depends on $subject series. A circular dependency. :-)

The dependency chain goes like this: "Tegra SDHCI update the pad
autocal procedure" -> "Tegra SDHCI enable 1.8 V signaling on Tegar210
and Tegra186" -> "Tegra PMC pinctrl pad configuration".

> In fact, there should be no dependency at all or else there seems to
> be a DT compatibility problem here...

From a functionality perspective there's no strict dependency, however,
I don't think "[PATCH v2 09/10] mmc: tegra: Perform pad calibration
after voltage switch" can be applied cleanly without
"[PATCH v2 03/10] mmc: tegra: Reconfigure pad voltages during voltage
switching" from the "Tegra SDHCI enable 1.8 V signaling on Tegar210 and
Tegra186" series.

> Anyway, I think it actually makes sense to fold in all changes into
> one series. Make sure the dt-doc changes comes first, then the driver
> changes and finally arm64/dts changes. This should make it easy to
> follow the review and I can pick the mmc parts and the soc maintainer
> can pick the arm64/dts changes.

I've sent the changes in multiple part because I've been working on
further changes to the driver while the previous parts have been
getting reviewed. This is still the case and there's still going to be
at least one more series which adds support for HS200 tuning and some
smaller changes after it. However, the HS200 work is probably going to
be ready for review in a day or two. I can send these as a one series
from now on, although at this point it would be 27 patches in total
and even more with the HS200 patches.

I can do that if you prefer to do it that way. Makes my life somewhat
easier too.

 -Aapo

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

* Re: [PATCH v2 00/10] Tegra SDHCI update the pad autocal procedure
@ 2018-07-30 15:43     ` Aapo Vienamo
  0 siblings, 0 replies; 29+ messages in thread
From: Aapo Vienamo @ 2018-07-30 15:43 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Rob Herring, Mark Rutland, Thierry Reding, Jonathan Hunter,
	Adrian Hunter, Mikko Perttunen, linux-mmc, devicetree,
	linux-tegra, Linux Kernel Mailing List

On Mon, 30 Jul 2018 17:07:59 +0200
Ulf Hansson <ulf.hansson@linaro.org> wrote:

> On 26 July 2018 at 14:26, Aapo Vienamo <avienamo@nvidia.com> wrote:
> > Hi all,
> >
> > Update the tegra_sdhci_pad_autocalib() pad drive strength calibration
> > procedure to match the ones specified in the TRMs of the more recent
> > SoCs. This was tested on Tegra186, Tegra210, and Tegra124, although it
> > should not break things older generations either.
> >
> > This series depends on the "Tegra SDHCI enable 1.8 V signaling on
> > Tegar210 and Tegra186" series posted earlier.  
> 
> According to the cover letter of the above series, it states that it
> depends on $subject series. A circular dependency. :-)

The dependency chain goes like this: "Tegra SDHCI update the pad
autocal procedure" -> "Tegra SDHCI enable 1.8 V signaling on Tegar210
and Tegra186" -> "Tegra PMC pinctrl pad configuration".

> In fact, there should be no dependency at all or else there seems to
> be a DT compatibility problem here...

>From a functionality perspective there's no strict dependency, however,
I don't think "[PATCH v2 09/10] mmc: tegra: Perform pad calibration
after voltage switch" can be applied cleanly without
"[PATCH v2 03/10] mmc: tegra: Reconfigure pad voltages during voltage
switching" from the "Tegra SDHCI enable 1.8 V signaling on Tegar210 and
Tegra186" series.

> Anyway, I think it actually makes sense to fold in all changes into
> one series. Make sure the dt-doc changes comes first, then the driver
> changes and finally arm64/dts changes. This should make it easy to
> follow the review and I can pick the mmc parts and the soc maintainer
> can pick the arm64/dts changes.

I've sent the changes in multiple part because I've been working on
further changes to the driver while the previous parts have been
getting reviewed. This is still the case and there's still going to be
at least one more series which adds support for HS200 tuning and some
smaller changes after it. However, the HS200 work is probably going to
be ready for review in a day or two. I can send these as a one series
from now on, although at this point it would be 27 patches in total
and even more with the HS200 patches.

I can do that if you prefer to do it that way. Makes my life somewhat
easier too.

 -Aapo

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

* Re: [PATCH v2 05/10] dt-bindings: Add Tegra SDHCI pad pdpu offset bindings
  2018-07-26 12:26   ` Aapo Vienamo
  (?)
@ 2018-07-30 23:31   ` Rob Herring
  -1 siblings, 0 replies; 29+ messages in thread
From: Rob Herring @ 2018-07-30 23:31 UTC (permalink / raw)
  To: Aapo Vienamo
  Cc: Ulf Hansson, Mark Rutland, Thierry Reding, Jonathan Hunter,
	Adrian Hunter, Mikko Perttunen, linux-mmc, devicetree,
	linux-tegra, linux-kernel

On Thu, Jul 26, 2018 at 03:26:51PM +0300, Aapo Vienamo wrote:
> Add bindings documentation for pad pull up and pull down offset values to be
> programmed before executing automatic pad drive strength calibration.
> 
> Signed-off-by: Aapo Vienamo <avienamo@nvidia.com>
> ---
>  .../bindings/mmc/nvidia,tegra20-sdhci.txt          | 34 ++++++++++++++++++++++
>  1 file changed, 34 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/mmc/nvidia,tegra20-sdhci.txt b/Documentation/devicetree/bindings/mmc/nvidia,tegra20-sdhci.txt
> index 95010cf..c3d8a15 100644
> --- a/Documentation/devicetree/bindings/mmc/nvidia,tegra20-sdhci.txt
> +++ b/Documentation/devicetree/bindings/mmc/nvidia,tegra20-sdhci.txt
> @@ -24,6 +24,7 @@ Required properties:
>  Optional properties:
>  - power-gpios : Specify GPIOs for power control
>  
> +Optional properties for Tegra210 and Tegra186:
>  Example:
>  
>  sdhci@c8000200 {
> @@ -47,6 +48,35 @@ Optional properties for Tegra210 and Tegra186:
>    pinctrl-1.
>  - nvidia,only-1-8-v : The presence of this property indicates that the
>    controller operates at a 1.8 V fixed I/O voltage.

> +- nvidia,pad-autocal-pull-up-offset-3v3,
> +  nvidia,pad-autocal-pull-down-offset-3v3 : Specify drive strength
> +  calibration offsets for 3.3 V signaling modes.

Perhaps a single property with 2 values?

> +- nvidia,pad-autocal-pull-up-offset-1v8,
> +  nvidia,pad-autocal-pull-down-offset-1v8 : Specify drive strength
> +  calibration offsets for 1.8 V signaling modes.
> +- nvidia,pad-autocal-pull-up-offset-3v3-timeout,
> +  nvidia,pad-autocal-pull-down-offset-3v3-timeout : Specify drive
> +  strength used as a fallback in case the automatic calibration times
> +  out on a 3.3 V signaling mode.
> +- nvidia,pad-autocal-pull-up-offset-1v8-timeout,
> +  nvidia,pad-autocal-pull-down-offset-1v8-timeout : Specify drive
> +  strength used as a fallback in case the automatic calibration times
> +  out on a 1.8 V signaling mode.
> +- nvidia,pad-autocal-pull-up-offset-sdr104,
> +  nvidia,pad-autocal-pull-down-offset-sdr104 : Specify drive strength
> +  calibration offsets for SDR104 mode.
> +- nvidia,pad-autocal-pull-up-offset-hs400,
> +  nvidia,pad-autocal-pull-down-offset-hs400 : Specify drive strength
> +  calibration offsets for HS400 mode.
> +
> +  Notes on the pad calibration pull up and pulldown offset values:
> +    - The property values are drive codes which are programmed into the
> +      PD_OFFSET and PU_OFFSET sections of the
> +      SDHCI_TEGRA_AUTO_CAL_CONFIG register.
> +    - A higher value corresponds to higher drive strength. Please refer
> +      to the reference manual of the SoC for correct values.
> +    - The SDR104 and HS400 timing specific values are used in
> +      corresponding modes if specified.
>  
>  Example:
>  sdhci@700b0000 {
> @@ -60,5 +90,9 @@ sdhci@700b0000 {
>  	pinctrl-names = "sdmmc-3v3", "sdmmc-1v8";
>  	pinctrl-0 = <&sdmmc1_3v3>;
>  	pinctrl-1 = <&sdmmc1_1v8>;
> +	pad-autocal-pull-up-offset-3v3 = <0x00>;
> +	pad-autocal-pull-down-offset-3v3 = <0x7d>;
> +	pad-autocal-pull-up-offset-1v8 = <0x7b>;
> +	pad-autocal-pull-down-offset-1v8 = <0x7b>;

Doesn't match the doc.

>  	status = "disabled";
>  };
> -- 
> 2.7.4
> 

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

* Re: [PATCH v2 00/10] Tegra SDHCI update the pad autocal procedure
  2018-07-30 15:43     ` Aapo Vienamo
  (?)
  (?)
@ 2018-07-31  9:33     ` Stefan Agner
  -1 siblings, 0 replies; 29+ messages in thread
From: Stefan Agner @ 2018-07-31  9:33 UTC (permalink / raw)
  To: Aapo Vienamo
  Cc: Ulf Hansson, Rob Herring, Mark Rutland, Thierry Reding,
	Jonathan Hunter, Adrian Hunter, Mikko Perttunen, linux-mmc,
	devicetree, linux-tegra, Linux Kernel Mailing List,
	linux-tegra-owner

On 30.07.2018 17:43, Aapo Vienamo wrote:
> On Mon, 30 Jul 2018 17:07:59 +0200
> Ulf Hansson <ulf.hansson@linaro.org> wrote:
> 
>> On 26 July 2018 at 14:26, Aapo Vienamo <avienamo@nvidia.com> wrote:
>> > Hi all,
>> >
>> > Update the tegra_sdhci_pad_autocalib() pad drive strength calibration
>> > procedure to match the ones specified in the TRMs of the more recent
>> > SoCs. This was tested on Tegra186, Tegra210, and Tegra124, although it
>> > should not break things older generations either.

I can give this a try on Tegra 3 here.

>> >
>> > This series depends on the "Tegra SDHCI enable 1.8 V signaling on
>> > Tegar210 and Tegra186" series posted earlier.
>>
>> According to the cover letter of the above series, it states that it
>> depends on $subject series. A circular dependency. :-)
> 
> The dependency chain goes like this: "Tegra SDHCI update the pad
> autocal procedure" -> "Tegra SDHCI enable 1.8 V signaling on Tegar210
> and Tegra186" -> "Tegra PMC pinctrl pad configuration".
> 
>> In fact, there should be no dependency at all or else there seems to
>> be a DT compatibility problem here...
> 
> From a functionality perspective there's no strict dependency, however,
> I don't think "[PATCH v2 09/10] mmc: tegra: Perform pad calibration
> after voltage switch" can be applied cleanly without
> "[PATCH v2 03/10] mmc: tegra: Reconfigure pad voltages during voltage
> switching" from the "Tegra SDHCI enable 1.8 V signaling on Tegar210 and
> Tegra186" series.
> 
>> Anyway, I think it actually makes sense to fold in all changes into
>> one series. Make sure the dt-doc changes comes first, then the driver
>> changes and finally arm64/dts changes. This should make it easy to
>> follow the review and I can pick the mmc parts and the soc maintainer
>> can pick the arm64/dts changes.
> 
> I've sent the changes in multiple part because I've been working on
> further changes to the driver while the previous parts have been
> getting reviewed. This is still the case and there's still going to be
> at least one more series which adds support for HS200 tuning and some
> smaller changes after it. However, the HS200 work is probably going to
> be ready for review in a day or two. I can send these as a one series
> from now on, although at this point it would be 27 patches in total
> and even more with the HS200 patches.
> 
> I can do that if you prefer to do it that way. Makes my life somewhat
> easier too.

...that would make it easier for my testing too, so I wait for the next
revision and will give it a try on Tegra 3 then.

--
Stefan

> 
>  -Aapo
> --
> To unsubscribe from this list: send the line "unsubscribe linux-tegra" 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] 29+ messages in thread

* Re: [PATCH v2 03/10] mmc: tegra: Power on the calibration pad
  2018-07-26 12:26   ` Aapo Vienamo
  (?)
@ 2018-07-31  9:41   ` Stefan Agner
  -1 siblings, 0 replies; 29+ messages in thread
From: Stefan Agner @ 2018-07-31  9:41 UTC (permalink / raw)
  To: Aapo Vienamo
  Cc: Ulf Hansson, Rob Herring, Mark Rutland, Thierry Reding,
	Jonathan Hunter, Adrian Hunter, Mikko Perttunen, linux-mmc,
	devicetree, linux-tegra, linux-kernel, linux-tegra-owner

On 26.07.2018 14:26, Aapo Vienamo wrote:
> Automatic pad drive strength calibration is performed on a separate pad
> identical to the ones used for driving the actual bus. Power on the
> calibration pad during the calibration procedure and power it off
> afterwards to save power.
> 
> Signed-off-by: Aapo Vienamo <avienamo@nvidia.com>
> Reviewed-by: Mikko Perttunen <mperttunen@nvidia.com>
> ---
>  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 51eda20..363490e 100644
> --- a/drivers/mmc/host/sdhci-tegra.c
> +++ b/drivers/mmc/host/sdhci-tegra.c
> @@ -53,6 +53,7 @@
>  #define SDHCI_TEGRA_SDMEM_COMP_PADCTRL			0x1e0
>  #define SDHCI_TEGRA_SDMEM_COMP_PADCTRL_VREF_SEL_MASK	0x0000000f
>  #define SDHCI_TEGRA_SDMEM_COMP_PADCTRL_VREF_SEL_VAL	0x7
> +#define SDHCI_TEGRA_SDMEM_COMP_PADCTRL_E_INPUT_E_PWRD	BIT(31)
>  
>  #define SDHCI_TEGRA_AUTO_CAL_STATUS			0x1ec
>  #define SDHCI_TEGRA_AUTO_CAL_ACTIVE			BIT(31)
> @@ -241,11 +242,30 @@ static void tegra_sdhci_reset(struct sdhci_host
> *host, u8 mask)
>  	tegra_host->ddr_signaling = false;
>  }
>  
> +static void tegra_sdhci_configure_cal_pad(struct sdhci_host *host, bool enable)
> +{
> +	u32 reg;
> +
> +	/*
> +	 * Enable or disable the additional I/O pad used by the drive strength
> +	 * calibration process.
> +	 */
> +	reg = sdhci_readl(host, SDHCI_TEGRA_SDMEM_COMP_PADCTRL);
> +	if (enable)
> +		reg |= SDHCI_TEGRA_SDMEM_COMP_PADCTRL_E_INPUT_E_PWRD;
> +	else
> +		reg &= ~SDHCI_TEGRA_SDMEM_COMP_PADCTRL_E_INPUT_E_PWRD;
> +	sdhci_writel(host, reg, SDHCI_TEGRA_SDMEM_COMP_PADCTRL);
> +	udelay(1);

Is this necessary on enable and disable?

If it only necessary on enable, I suggest to move it after the call to:
tegra_sdhci_configure_cal_pad(host, true);

--
Stefan

> +}
> +
>  static void tegra_sdhci_pad_autocalib(struct sdhci_host *host)
>  {
>  	u32 reg;
>  	int ret;
>  
> +	tegra_sdhci_configure_cal_pad(host, true);
> +
>  	reg = sdhci_readl(host, SDHCI_TEGRA_AUTO_CAL_CONFIG);
>  	reg |= SDHCI_AUTO_CAL_ENABLE | SDHCI_AUTO_CAL_START;
>  	sdhci_writel(host, reg, SDHCI_TEGRA_AUTO_CAL_CONFIG);
> @@ -255,6 +275,8 @@ static void tegra_sdhci_pad_autocalib(struct
> sdhci_host *host)
>  				 reg, !(reg & SDHCI_TEGRA_AUTO_CAL_ACTIVE),
>  				 1, 10000);
>  
> +	tegra_sdhci_configure_cal_pad(host, false);
> +
>  	if (ret)
>  		dev_err(mmc_dev(host->mmc), "Pad autocal timed out\n");
>  }

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

end of thread, other threads:[~2018-07-31  9:41 UTC | newest]

Thread overview: 29+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-07-26 12:26 [PATCH v2 00/10] Tegra SDHCI update the pad autocal procedure Aapo Vienamo
2018-07-26 12:26 ` Aapo Vienamo
2018-07-26 12:26 ` [PATCH v2 01/10] mmc: tegra: Poll for calibration completion Aapo Vienamo
2018-07-26 12:26   ` Aapo Vienamo
2018-07-26 12:26 ` [PATCH v2 02/10] mmc: tegra: Set calibration pad voltage reference Aapo Vienamo
2018-07-26 12:26   ` Aapo Vienamo
2018-07-26 12:26 ` [PATCH v2 03/10] mmc: tegra: Power on the calibration pad Aapo Vienamo
2018-07-26 12:26   ` Aapo Vienamo
2018-07-31  9:41   ` Stefan Agner
2018-07-26 12:26 ` [PATCH v2 04/10] mmc: tegra: Disable card clock during pad calibration Aapo Vienamo
2018-07-26 12:26   ` Aapo Vienamo
2018-07-26 12:26 ` [PATCH v2 05/10] dt-bindings: Add Tegra SDHCI pad pdpu offset bindings Aapo Vienamo
2018-07-26 12:26   ` Aapo Vienamo
2018-07-30 23:31   ` Rob Herring
2018-07-26 12:26 ` [PATCH v2 06/10] mmc: tegra: Program pad autocal offsets from dt Aapo Vienamo
2018-07-26 12:26   ` Aapo Vienamo
2018-07-26 12:26 ` [PATCH v2 07/10] arm64: dts: tegra186: Add sdmmc pad auto calibration offsets Aapo Vienamo
2018-07-26 12:26   ` Aapo Vienamo
2018-07-26 12:26 ` [PATCH v2 08/10] arm64: dts: tegra210: " Aapo Vienamo
2018-07-26 12:26   ` Aapo Vienamo
2018-07-26 12:26 ` [PATCH v2 09/10] mmc: tegra: Perform pad calibration after voltage switch Aapo Vienamo
2018-07-26 12:26   ` Aapo Vienamo
2018-07-26 12:26 ` [PATCH v2 10/10] mmc: tegra: Enable pad calibration on Tegra210 and Tegra186 Aapo Vienamo
2018-07-26 12:26   ` Aapo Vienamo
2018-07-30 15:07 ` [PATCH v2 00/10] Tegra SDHCI update the pad autocal procedure Ulf Hansson
2018-07-30 15:43   ` Aapo Vienamo
2018-07-30 15:43     ` Aapo Vienamo
2018-07-30 15:43     ` Aapo Vienamo
2018-07-31  9:33     ` Stefan Agner

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.