2020-08-04 04:30:19

by Sowjanya Komatineni

[permalink] [raw]
Subject: [PATCH v2 0/6] Fix timeout clock used by hardware data timeout

Tegra210/Tegra186/Tegra194 has incorrectly enabled
SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK from the beginning of their support.

Tegra210 and later SDMMC hardware default uses sdmmc_legacy_tm (TMCLK)
all the time for hardware data timeout instead of SDCLK and this TMCLK
need to be kept enabled by Tegra sdmmc driver.

This series includes patches to fix this for Tegra210/Tegra186/Tegra194.

These patches need to be manually backported for 4.9, 4.14, 4.19, 5.4

Will send patches to backport separately once these patches are ack'd.

Delta between patch versions:
[v2]: Includes minor fix
- Patch-0006: parentheses around operand of '!'

Sowjanya Komatineni (6):
sdhci: tegra: Remove SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK for Tegra210
sdhci: tegra: Remove SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK for Tegra186
arm64: tegra: Add missing timeout clock to Tegra210 SDMMC
arm64: tegra: Add missing timeout clock to Tegra186 SDMMC nodes
arm64: tegra: Add missing timeout clock to Tegra194 SDMMC nodes
sdhci: tegra: Add missing TMCLK for data timeout

arch/arm64/boot/dts/nvidia/tegra186.dtsi | 20 +++++++++------
arch/arm64/boot/dts/nvidia/tegra194.dtsi | 15 ++++++-----
arch/arm64/boot/dts/nvidia/tegra210.dtsi | 20 +++++++++------
drivers/mmc/host/sdhci-tegra.c | 43 ++++++++++++++++++++++++++++++--
4 files changed, 74 insertions(+), 24 deletions(-)

--
2.7.4


2020-08-04 04:31:07

by Sowjanya Komatineni

[permalink] [raw]
Subject: [PATCH v2 6/6] sdhci: tegra: Add missing TMCLK for data timeout

commit b5a84ecf025a ("mmc: tegra: Add Tegra210 support")

Tegra210 and later has a separate sdmmc_legacy_tm (TMCLK) used by Tegra
SDMMC hawdware for data timeout to achive better timeout than using
SDCLK and using TMCLK is recommended.

USE_TMCLK_FOR_DATA_TIMEOUT bit in Tegra SDMMC register
SDHCI_TEGRA_VENDOR_SYS_SW_CTRL can be used to choose either TMCLK or
SDCLK for data timeout.

Default USE_TMCLK_FOR_DATA_TIMEOUT bit is set to 1 and TMCLK is used
for data timeout by Tegra SDMMC hardware and having TMCLK not enabled
is not recommended.

So, this patch fixes it.

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

diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c
index 31ed321..c0b9405 100644
--- a/drivers/mmc/host/sdhci-tegra.c
+++ b/drivers/mmc/host/sdhci-tegra.c
@@ -140,6 +140,7 @@ struct sdhci_tegra_autocal_offsets {
struct sdhci_tegra {
const struct sdhci_tegra_soc_data *soc_data;
struct gpio_desc *power_gpio;
+ struct clk *tmclk;
bool ddr_signaling;
bool pad_calib_required;
bool pad_control_available;
@@ -1611,6 +1612,44 @@ static int sdhci_tegra_probe(struct platform_device *pdev)
goto err_power_req;
}

+ /*
+ * Tegra210 has a separate SDMMC_LEGACY_TM clock used for host
+ * timeout clock and SW can choose TMCLK or SDCLK for hardware
+ * data timeout through the bit USE_TMCLK_FOR_DATA_TIMEOUT of
+ * the register SDHCI_TEGRA_VENDOR_SYS_SW_CTRL.
+ *
+ * USE_TMCLK_FOR_DATA_TIMEOUT bit default is set to 1 and SDMMC uses
+ * 12Mhz TMCLK which is advertised in host capability register.
+ * With TMCLK of 12Mhz provides maximum data timeout period that can
+ * be achieved is 11s better than using SDCLK for data timeout.
+ *
+ * So, TMCLK is set to 12Mhz and kept enabled all the time on SoC's
+ * supporting SDR104 mode and when not using SDCLK for data timeout.
+ */
+
+ if ((soc_data->nvquirks & NVQUIRK_ENABLE_SDR104) &&
+ !(soc_data->pdata->quirks & SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK)) {
+ clk = devm_clk_get(&pdev->dev, "tmclk");
+ if (IS_ERR(clk)) {
+ rc = PTR_ERR(clk);
+ if (rc == -EPROBE_DEFER)
+ goto err_power_req;
+
+ dev_warn(&pdev->dev, "failed to get tmclk: %d\n", rc);
+ clk = NULL;
+ }
+
+ clk_set_rate(clk, 12000000);
+ rc = clk_prepare_enable(clk);
+ if (rc) {
+ dev_err(&pdev->dev,
+ "failed to enable tmclk: %d\n", rc);
+ goto err_power_req;
+ }
+
+ tegra_host->tmclk = clk;
+ }
+
clk = devm_clk_get(mmc_dev(host->mmc), NULL);
if (IS_ERR(clk)) {
rc = PTR_ERR(clk);
@@ -1654,6 +1693,7 @@ static int sdhci_tegra_probe(struct platform_device *pdev)
err_rst_get:
clk_disable_unprepare(pltfm_host->clk);
err_clk_get:
+ clk_disable_unprepare(tegra_host->tmclk);
err_power_req:
err_parse_dt:
sdhci_pltfm_free(pdev);
@@ -1671,6 +1711,7 @@ static int sdhci_tegra_remove(struct platform_device *pdev)
reset_control_assert(tegra_host->rst);
usleep_range(2000, 4000);
clk_disable_unprepare(pltfm_host->clk);
+ clk_disable_unprepare(tegra_host->tmclk);

sdhci_pltfm_free(pdev);

--
2.7.4

2020-08-04 04:31:20

by Sowjanya Komatineni

[permalink] [raw]
Subject: [PATCH v2 2/6] sdhci: tegra: Remove SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK for Tegra186

commit 4346b7c7941d ("mmc: tegra: Add Tegra186 support")

SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK is set for Tegra186 from the
beginning of its support in driver.

Tegra186 SDMMC hardware by default uses timeout clock (TMCLK) instead
of SDCLK and this quirk should not be set.

So, this patch remove this quirk for Tegra186.

Signed-off-by: Sowjanya Komatineni <[email protected]>
---
drivers/mmc/host/sdhci-tegra.c | 1 -
1 file changed, 1 deletion(-)

diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c
index 2be3511..31ed321 100644
--- a/drivers/mmc/host/sdhci-tegra.c
+++ b/drivers/mmc/host/sdhci-tegra.c
@@ -1455,7 +1455,6 @@ static const struct sdhci_ops tegra186_sdhci_ops = {

static const struct sdhci_pltfm_data sdhci_tegra186_pdata = {
.quirks = SDHCI_QUIRK_BROKEN_TIMEOUT_VAL |
- SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK |
SDHCI_QUIRK_SINGLE_POWER_WRITE |
SDHCI_QUIRK_NO_HISPD_BIT |
SDHCI_QUIRK_BROKEN_ADMA_ZEROLEN_DESC |
--
2.7.4

2020-08-05 07:56:51

by Adrian Hunter

[permalink] [raw]
Subject: Re: [PATCH v2 2/6] sdhci: tegra: Remove SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK for Tegra186

On 4/08/20 7:29 am, Sowjanya Komatineni wrote:
> commit 4346b7c7941d ("mmc: tegra: Add Tegra186 support")

So that could be a Fixes tag also?

>
> SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK is set for Tegra186 from the
> beginning of its support in driver.
>
> Tegra186 SDMMC hardware by default uses timeout clock (TMCLK) instead
> of SDCLK and this quirk should not be set.
>
> So, this patch remove this quirk for Tegra186.
>
> Signed-off-by: Sowjanya Komatineni <[email protected]>

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

> ---
> drivers/mmc/host/sdhci-tegra.c | 1 -
> 1 file changed, 1 deletion(-)
>
> diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c
> index 2be3511..31ed321 100644
> --- a/drivers/mmc/host/sdhci-tegra.c
> +++ b/drivers/mmc/host/sdhci-tegra.c
> @@ -1455,7 +1455,6 @@ static const struct sdhci_ops tegra186_sdhci_ops = {
>
> static const struct sdhci_pltfm_data sdhci_tegra186_pdata = {
> .quirks = SDHCI_QUIRK_BROKEN_TIMEOUT_VAL |
> - SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK |
> SDHCI_QUIRK_SINGLE_POWER_WRITE |
> SDHCI_QUIRK_NO_HISPD_BIT |
> SDHCI_QUIRK_BROKEN_ADMA_ZEROLEN_DESC |
>

2020-08-05 08:10:51

by Adrian Hunter

[permalink] [raw]
Subject: Re: [PATCH v2 6/6] sdhci: tegra: Add missing TMCLK for data timeout

On 4/08/20 7:29 am, Sowjanya Komatineni wrote:
> commit b5a84ecf025a ("mmc: tegra: Add Tegra210 support")

So that could be a Fixes tag also?

>
> Tegra210 and later has a separate sdmmc_legacy_tm (TMCLK) used by Tegra
> SDMMC hawdware for data timeout to achive better timeout than using
> SDCLK and using TMCLK is recommended.
>
> USE_TMCLK_FOR_DATA_TIMEOUT bit in Tegra SDMMC register
> SDHCI_TEGRA_VENDOR_SYS_SW_CTRL can be used to choose either TMCLK or
> SDCLK for data timeout.
>
> Default USE_TMCLK_FOR_DATA_TIMEOUT bit is set to 1 and TMCLK is used
> for data timeout by Tegra SDMMC hardware and having TMCLK not enabled
> is not recommended.
>
> So, this patch fixes it.
>
> Signed-off-by: Sowjanya Komatineni <[email protected]>

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

> ---
> drivers/mmc/host/sdhci-tegra.c | 41 +++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 41 insertions(+)
>
> diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c
> index 31ed321..c0b9405 100644
> --- a/drivers/mmc/host/sdhci-tegra.c
> +++ b/drivers/mmc/host/sdhci-tegra.c
> @@ -140,6 +140,7 @@ struct sdhci_tegra_autocal_offsets {
> struct sdhci_tegra {
> const struct sdhci_tegra_soc_data *soc_data;
> struct gpio_desc *power_gpio;
> + struct clk *tmclk;
> bool ddr_signaling;
> bool pad_calib_required;
> bool pad_control_available;
> @@ -1611,6 +1612,44 @@ static int sdhci_tegra_probe(struct platform_device *pdev)
> goto err_power_req;
> }
>
> + /*
> + * Tegra210 has a separate SDMMC_LEGACY_TM clock used for host
> + * timeout clock and SW can choose TMCLK or SDCLK for hardware
> + * data timeout through the bit USE_TMCLK_FOR_DATA_TIMEOUT of
> + * the register SDHCI_TEGRA_VENDOR_SYS_SW_CTRL.
> + *
> + * USE_TMCLK_FOR_DATA_TIMEOUT bit default is set to 1 and SDMMC uses
> + * 12Mhz TMCLK which is advertised in host capability register.
> + * With TMCLK of 12Mhz provides maximum data timeout period that can
> + * be achieved is 11s better than using SDCLK for data timeout.
> + *
> + * So, TMCLK is set to 12Mhz and kept enabled all the time on SoC's
> + * supporting SDR104 mode and when not using SDCLK for data timeout.
> + */
> +
> + if ((soc_data->nvquirks & NVQUIRK_ENABLE_SDR104) &&
> + !(soc_data->pdata->quirks & SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK)) {
> + clk = devm_clk_get(&pdev->dev, "tmclk");
> + if (IS_ERR(clk)) {
> + rc = PTR_ERR(clk);
> + if (rc == -EPROBE_DEFER)
> + goto err_power_req;
> +
> + dev_warn(&pdev->dev, "failed to get tmclk: %d\n", rc);
> + clk = NULL;
> + }
> +
> + clk_set_rate(clk, 12000000);
> + rc = clk_prepare_enable(clk);
> + if (rc) {
> + dev_err(&pdev->dev,
> + "failed to enable tmclk: %d\n", rc);
> + goto err_power_req;
> + }
> +
> + tegra_host->tmclk = clk;
> + }
> +
> clk = devm_clk_get(mmc_dev(host->mmc), NULL);
> if (IS_ERR(clk)) {
> rc = PTR_ERR(clk);
> @@ -1654,6 +1693,7 @@ static int sdhci_tegra_probe(struct platform_device *pdev)
> err_rst_get:
> clk_disable_unprepare(pltfm_host->clk);
> err_clk_get:
> + clk_disable_unprepare(tegra_host->tmclk);
> err_power_req:
> err_parse_dt:
> sdhci_pltfm_free(pdev);
> @@ -1671,6 +1711,7 @@ static int sdhci_tegra_remove(struct platform_device *pdev)
> reset_control_assert(tegra_host->rst);
> usleep_range(2000, 4000);
> clk_disable_unprepare(pltfm_host->clk);
> + clk_disable_unprepare(tegra_host->tmclk);
>
> sdhci_pltfm_free(pdev);
>
>

2020-08-06 00:10:21

by Sowjanya Komatineni

[permalink] [raw]
Subject: Re: [PATCH v2 6/6] sdhci: tegra: Add missing TMCLK for data timeout


On 8/5/20 1:06 AM, Adrian Hunter wrote:
> On 4/08/20 7:29 am, Sowjanya Komatineni wrote:
>> commit b5a84ecf025a ("mmc: tegra: Add Tegra210 support")
> So that could be a Fixes tag also?

Thanks Adrian. Will resend with fixes tag.

Sowjanya

>
>> Tegra210 and later has a separate sdmmc_legacy_tm (TMCLK) used by Tegra
>> SDMMC hawdware for data timeout to achive better timeout than using
>> SDCLK and using TMCLK is recommended.
>>
>> USE_TMCLK_FOR_DATA_TIMEOUT bit in Tegra SDMMC register
>> SDHCI_TEGRA_VENDOR_SYS_SW_CTRL can be used to choose either TMCLK or
>> SDCLK for data timeout.
>>
>> Default USE_TMCLK_FOR_DATA_TIMEOUT bit is set to 1 and TMCLK is used
>> for data timeout by Tegra SDMMC hardware and having TMCLK not enabled
>> is not recommended.
>>
>> So, this patch fixes it.
>>
>> Signed-off-by: Sowjanya Komatineni <[email protected]>
> Acked-by: Adrian Hunter <[email protected]>
>
>> ---
>> drivers/mmc/host/sdhci-tegra.c | 41 +++++++++++++++++++++++++++++++++++++++++
>> 1 file changed, 41 insertions(+)
>>
>> diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c
>> index 31ed321..c0b9405 100644
>> --- a/drivers/mmc/host/sdhci-tegra.c
>> +++ b/drivers/mmc/host/sdhci-tegra.c
>> @@ -140,6 +140,7 @@ struct sdhci_tegra_autocal_offsets {
>> struct sdhci_tegra {
>> const struct sdhci_tegra_soc_data *soc_data;
>> struct gpio_desc *power_gpio;
>> + struct clk *tmclk;
>> bool ddr_signaling;
>> bool pad_calib_required;
>> bool pad_control_available;
>> @@ -1611,6 +1612,44 @@ static int sdhci_tegra_probe(struct platform_device *pdev)
>> goto err_power_req;
>> }
>>
>> + /*
>> + * Tegra210 has a separate SDMMC_LEGACY_TM clock used for host
>> + * timeout clock and SW can choose TMCLK or SDCLK for hardware
>> + * data timeout through the bit USE_TMCLK_FOR_DATA_TIMEOUT of
>> + * the register SDHCI_TEGRA_VENDOR_SYS_SW_CTRL.
>> + *
>> + * USE_TMCLK_FOR_DATA_TIMEOUT bit default is set to 1 and SDMMC uses
>> + * 12Mhz TMCLK which is advertised in host capability register.
>> + * With TMCLK of 12Mhz provides maximum data timeout period that can
>> + * be achieved is 11s better than using SDCLK for data timeout.
>> + *
>> + * So, TMCLK is set to 12Mhz and kept enabled all the time on SoC's
>> + * supporting SDR104 mode and when not using SDCLK for data timeout.
>> + */
>> +
>> + if ((soc_data->nvquirks & NVQUIRK_ENABLE_SDR104) &&
>> + !(soc_data->pdata->quirks & SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK)) {
>> + clk = devm_clk_get(&pdev->dev, "tmclk");
>> + if (IS_ERR(clk)) {
>> + rc = PTR_ERR(clk);
>> + if (rc == -EPROBE_DEFER)
>> + goto err_power_req;
>> +
>> + dev_warn(&pdev->dev, "failed to get tmclk: %d\n", rc);
>> + clk = NULL;
>> + }
>> +
>> + clk_set_rate(clk, 12000000);
>> + rc = clk_prepare_enable(clk);
>> + if (rc) {
>> + dev_err(&pdev->dev,
>> + "failed to enable tmclk: %d\n", rc);
>> + goto err_power_req;
>> + }
>> +
>> + tegra_host->tmclk = clk;
>> + }
>> +
>> clk = devm_clk_get(mmc_dev(host->mmc), NULL);
>> if (IS_ERR(clk)) {
>> rc = PTR_ERR(clk);
>> @@ -1654,6 +1693,7 @@ static int sdhci_tegra_probe(struct platform_device *pdev)
>> err_rst_get:
>> clk_disable_unprepare(pltfm_host->clk);
>> err_clk_get:
>> + clk_disable_unprepare(tegra_host->tmclk);
>> err_power_req:
>> err_parse_dt:
>> sdhci_pltfm_free(pdev);
>> @@ -1671,6 +1711,7 @@ static int sdhci_tegra_remove(struct platform_device *pdev)
>> reset_control_assert(tegra_host->rst);
>> usleep_range(2000, 4000);
>> clk_disable_unprepare(pltfm_host->clk);
>> + clk_disable_unprepare(tegra_host->tmclk);
>>
>> sdhci_pltfm_free(pdev);
>>
>>