2020-08-26 20:06:39

by Sowjanya Komatineni

[permalink] [raw]
Subject: [PATCH v5 0/7] 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 and 4.19.

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

Delta between patch versions:
[v5]: Include below changes based on v4 feedback
- updated dt-binding doc to be more clear
- updated Tegra sdhci driver to retrieve sdhci and tmclk clocks
based on no. of clocks in sdhci device node as old device trees
do not use sdhci clock name and this allows proper clock retrival
irrespective of sdhci and tmclk clocks order in device tree.
- Added separate quirk for identifying SoC's supporting separate
timeout clock to be more clear.

[v4]: Include additional dt-binding patch

[v3]: Same as v2 with fixes tag

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

Sowjanya Komatineni (7):
sdhci: tegra: Remove SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK for Tegra210
sdhci: tegra: Remove SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK for Tegra186
dt-bindings: mmc: tegra: Add tmclk for Tegra210 and later
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

.../bindings/mmc/nvidia,tegra20-sdhci.txt | 32 +++++++-
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 | 91 +++++++++++++++++++---
5 files changed, 143 insertions(+), 35 deletions(-)

--
2.7.4


2020-08-26 20:06:55

by Sowjanya Komatineni

[permalink] [raw]
Subject: [PATCH v5 5/7] arm64: tegra: Add missing timeout clock to Tegra186 SDMMC nodes

commit 39cb62cb8973 ("arm64: tegra: Add Tegra186 support")

Tegra186 uses separate SDMMC_LEGACY_TM clock for data timeout and
this clock is not enabled currently which is not recommended.

Tegra186 SDMMC advertises 12Mhz as timeout clock frequency in host
capability register and uses it by default.

So, this clock should be kept enabled by the SDMMC driver.

Fixes: 39cb62cb8973 ("arm64: tegra: Add Tegra186 support")
Cc: stable <[email protected]> # 5.4
Tested-by: Jon Hunter <[email protected]>
Reviewed-by: Jon Hunter <[email protected]>
Signed-off-by: Sowjanya Komatineni <[email protected]>
---
arch/arm64/boot/dts/nvidia/tegra186.dtsi | 20 ++++++++++++--------
1 file changed, 12 insertions(+), 8 deletions(-)

diff --git a/arch/arm64/boot/dts/nvidia/tegra186.dtsi b/arch/arm64/boot/dts/nvidia/tegra186.dtsi
index 34d249d..8eb61dd 100644
--- a/arch/arm64/boot/dts/nvidia/tegra186.dtsi
+++ b/arch/arm64/boot/dts/nvidia/tegra186.dtsi
@@ -337,8 +337,9 @@
compatible = "nvidia,tegra186-sdhci";
reg = <0x0 0x03400000 0x0 0x10000>;
interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&bpmp TEGRA186_CLK_SDMMC1>;
- clock-names = "sdhci";
+ clocks = <&bpmp TEGRA186_CLK_SDMMC1>,
+ <&bpmp TEGRA186_CLK_SDMMC_LEGACY_TM>;
+ clock-names = "sdhci", "tmclk";
resets = <&bpmp TEGRA186_RESET_SDMMC1>;
reset-names = "sdhci";
interconnects = <&mc TEGRA186_MEMORY_CLIENT_SDMMCRA &emc>,
@@ -366,8 +367,9 @@
compatible = "nvidia,tegra186-sdhci";
reg = <0x0 0x03420000 0x0 0x10000>;
interrupts = <GIC_SPI 63 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&bpmp TEGRA186_CLK_SDMMC2>;
- clock-names = "sdhci";
+ clocks = <&bpmp TEGRA186_CLK_SDMMC2>,
+ <&bpmp TEGRA186_CLK_SDMMC_LEGACY_TM>;
+ clock-names = "sdhci", "tmclk";
resets = <&bpmp TEGRA186_RESET_SDMMC2>;
reset-names = "sdhci";
interconnects = <&mc TEGRA186_MEMORY_CLIENT_SDMMCRAA &emc>,
@@ -390,8 +392,9 @@
compatible = "nvidia,tegra186-sdhci";
reg = <0x0 0x03440000 0x0 0x10000>;
interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&bpmp TEGRA186_CLK_SDMMC3>;
- clock-names = "sdhci";
+ clocks = <&bpmp TEGRA186_CLK_SDMMC3>,
+ <&bpmp TEGRA186_CLK_SDMMC_LEGACY_TM>;
+ clock-names = "sdhci", "tmclk";
resets = <&bpmp TEGRA186_RESET_SDMMC3>;
reset-names = "sdhci";
interconnects = <&mc TEGRA186_MEMORY_CLIENT_SDMMCR &emc>,
@@ -416,8 +419,9 @@
compatible = "nvidia,tegra186-sdhci";
reg = <0x0 0x03460000 0x0 0x10000>;
interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&bpmp TEGRA186_CLK_SDMMC4>;
- clock-names = "sdhci";
+ clocks = <&bpmp TEGRA186_CLK_SDMMC4>,
+ <&bpmp TEGRA186_CLK_SDMMC_LEGACY_TM>;
+ clock-names = "sdhci", "tmclk";
assigned-clocks = <&bpmp TEGRA186_CLK_SDMMC4>,
<&bpmp TEGRA186_CLK_PLLC4_VCO>;
assigned-clock-parents = <&bpmp TEGRA186_CLK_PLLC4_VCO>;
--
2.7.4

2020-08-26 20:07:04

by Sowjanya Komatineni

[permalink] [raw]
Subject: [PATCH v5 4/7] arm64: tegra: Add missing timeout clock to Tegra210 SDMMC

commit 742af7e7a0a1 ("arm64: tegra: Add Tegra210 support")

Tegra210 uses separate SDMMC_LEGACY_TM clock for data timeout and
this clock is not enabled currently which is not recommended.

Tegra SDMMC advertises 12Mhz as timeout clock frequency in host
capability register.

So, this clock should be kept enabled by SDMMC driver.

Fixes: 742af7e7a0a1 ("arm64: tegra: Add Tegra210 support")
Cc: stable <[email protected]> # 5.4
Tested-by: Jon Hunter <[email protected]>
Reviewed-by: Jon Hunter <[email protected]>
Signed-off-by: Sowjanya Komatineni <[email protected]>
---
arch/arm64/boot/dts/nvidia/tegra210.dtsi | 20 ++++++++++++--------
1 file changed, 12 insertions(+), 8 deletions(-)

diff --git a/arch/arm64/boot/dts/nvidia/tegra210.dtsi b/arch/arm64/boot/dts/nvidia/tegra210.dtsi
index 829f786..8cca216 100644
--- a/arch/arm64/boot/dts/nvidia/tegra210.dtsi
+++ b/arch/arm64/boot/dts/nvidia/tegra210.dtsi
@@ -1194,8 +1194,9 @@
compatible = "nvidia,tegra210-sdhci";
reg = <0x0 0x700b0000 0x0 0x200>;
interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&tegra_car TEGRA210_CLK_SDMMC1>;
- clock-names = "sdhci";
+ clocks = <&tegra_car TEGRA210_CLK_SDMMC1>,
+ <&tegra_car TEGRA210_CLK_SDMMC_LEGACY>;
+ clock-names = "sdhci", "tmclk";
resets = <&tegra_car 14>;
reset-names = "sdhci";
pinctrl-names = "sdmmc-3v3", "sdmmc-1v8",
@@ -1222,8 +1223,9 @@
compatible = "nvidia,tegra210-sdhci";
reg = <0x0 0x700b0200 0x0 0x200>;
interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&tegra_car TEGRA210_CLK_SDMMC2>;
- clock-names = "sdhci";
+ clocks = <&tegra_car TEGRA210_CLK_SDMMC2>,
+ <&tegra_car TEGRA210_CLK_SDMMC_LEGACY>;
+ clock-names = "sdhci", "tmclk";
resets = <&tegra_car 9>;
reset-names = "sdhci";
pinctrl-names = "sdmmc-1v8-drv";
@@ -1239,8 +1241,9 @@
compatible = "nvidia,tegra210-sdhci";
reg = <0x0 0x700b0400 0x0 0x200>;
interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&tegra_car TEGRA210_CLK_SDMMC3>;
- clock-names = "sdhci";
+ clocks = <&tegra_car TEGRA210_CLK_SDMMC3>,
+ <&tegra_car TEGRA210_CLK_SDMMC_LEGACY>;
+ clock-names = "sdhci", "tmclk";
resets = <&tegra_car 69>;
reset-names = "sdhci";
pinctrl-names = "sdmmc-3v3", "sdmmc-1v8",
@@ -1262,8 +1265,9 @@
compatible = "nvidia,tegra210-sdhci";
reg = <0x0 0x700b0600 0x0 0x200>;
interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&tegra_car TEGRA210_CLK_SDMMC4>;
- clock-names = "sdhci";
+ clocks = <&tegra_car TEGRA210_CLK_SDMMC4>,
+ <&tegra_car TEGRA210_CLK_SDMMC_LEGACY>;
+ clock-names = "sdhci", "tmclk";
resets = <&tegra_car 15>;
reset-names = "sdhci";
pinctrl-names = "sdmmc-3v3-drv", "sdmmc-1v8-drv";
--
2.7.4

2020-08-26 20:07:33

by Sowjanya Komatineni

[permalink] [raw]
Subject: [PATCH v5 7/7] 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 adds quirk NVQUIRK_HAS_TMCLK for SoC having separate
timeout clock and keeps TMCLK enabled all the time.

Fixes: b5a84ecf025a ("mmc: tegra: Add Tegra210 support")
Cc: stable <[email protected]> # 5.4
Tested-by: Jon Hunter <[email protected]>
Reviewed-by: Jon Hunter <[email protected]>
Acked-by: Adrian Hunter <[email protected]>
Signed-off-by: Sowjanya Komatineni <[email protected]>
---
drivers/mmc/host/sdhci-tegra.c | 89 ++++++++++++++++++++++++++++++++++++++----
1 file changed, 81 insertions(+), 8 deletions(-)

diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c
index 31ed321..9bcd532 100644
--- a/drivers/mmc/host/sdhci-tegra.c
+++ b/drivers/mmc/host/sdhci-tegra.c
@@ -110,6 +110,12 @@
#define NVQUIRK_DIS_CARD_CLK_CONFIG_TAP BIT(8)
#define NVQUIRK_CQHCI_DCMD_R1B_CMD_TIMING BIT(9)

+/*
+ * NVQUIRK_HAS_TMCLK is for SoC's having separate timeout clock for Tegra
+ * SDMMC hardware data timeout.
+ */
+#define NVQUIRK_HAS_TMCLK BIT(10)
+
/* SDMMC CQE Base Address for Tegra Host Ver 4.1 and Higher */
#define SDHCI_TEGRA_CQE_BASE_ADDR 0xF000

@@ -140,6 +146,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;
@@ -1433,7 +1440,8 @@ static const struct sdhci_tegra_soc_data soc_data_tegra210 = {
NVQUIRK_HAS_PADCALIB |
NVQUIRK_DIS_CARD_CLK_CONFIG_TAP |
NVQUIRK_ENABLE_SDR50 |
- NVQUIRK_ENABLE_SDR104,
+ NVQUIRK_ENABLE_SDR104 |
+ NVQUIRK_HAS_TMCLK,
.min_tap_delay = 106,
.max_tap_delay = 185,
};
@@ -1471,6 +1479,7 @@ static const struct sdhci_tegra_soc_data soc_data_tegra186 = {
NVQUIRK_DIS_CARD_CLK_CONFIG_TAP |
NVQUIRK_ENABLE_SDR50 |
NVQUIRK_ENABLE_SDR104 |
+ NVQUIRK_HAS_TMCLK |
NVQUIRK_CQHCI_DCMD_R1B_CMD_TIMING,
.min_tap_delay = 84,
.max_tap_delay = 136,
@@ -1483,7 +1492,8 @@ static const struct sdhci_tegra_soc_data soc_data_tegra194 = {
NVQUIRK_HAS_PADCALIB |
NVQUIRK_DIS_CARD_CLK_CONFIG_TAP |
NVQUIRK_ENABLE_SDR50 |
- NVQUIRK_ENABLE_SDR104,
+ NVQUIRK_ENABLE_SDR104 |
+ NVQUIRK_HAS_TMCLK;
.min_tap_delay = 96,
.max_tap_delay = 139,
};
@@ -1611,15 +1621,76 @@ static int sdhci_tegra_probe(struct platform_device *pdev)
goto err_power_req;
}

- clk = devm_clk_get(mmc_dev(host->mmc), NULL);
- if (IS_ERR(clk)) {
- rc = PTR_ERR(clk);
+ /*
+ * Tegra210 and later has separate SDMMC_LEGACY_TM clock used for
+ * hardware data 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 separate TMCLK.
+ *
+ * Old device tree has single sdhci clock. So with addition of TMCLK,
+ * retrieving sdhci clock by "sdhci" clock name based on number of
+ * clocks in sdhci device node.
+ */
+
+ if (of_clk_get_parent_count(&pdev->dev) == 1) {
+ if (soc_data->nvquirks & NVQUIRK_HAS_TMCLK)
+ dev_warn(&pdev->dev,
+ "missing tmclk in the device tree\n");
+
+ clk = devm_clk_get(dev, NULL)
+ if (IS_ERR(clk)) {
+ rc = PTR_ERR(clk);

- if (rc != -EPROBE_DEFER)
- dev_err(&pdev->dev, "failed to get clock: %d\n", rc);
+ if (rc != -EPROBE_DEFER)
+ dev_err(&pdev->dev,
+ "failed to get sdhci clock: %d\n", rc);

- goto err_clk_get;
+ goto err_power_req;
+ }
+ } else {
+ if (soc_data->nvquirks & NVQUIRK_HAS_TMCLK) {
+ 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(dev, "sdhci")
+ if (IS_ERR(clk)) {
+ rc = PTR_ERR(clk);
+
+ if (rc != -EPROBE_DEFER)
+ dev_err(&pdev->dev,
+ "failed to get sdhci clock: %d\n", rc);
+
+ goto err_clk_get;
+ }
}
+
clk_prepare_enable(clk);
pltfm_host->clk = clk;

@@ -1654,6 +1725,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 +1743,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-26 20:07:41

by Sowjanya Komatineni

[permalink] [raw]
Subject: [PATCH v5 6/7] arm64: tegra: Add missing timeout clock to Tegra194 SDMMC nodes

commit 5425fb15d8ee ("arm64: tegra: Add Tegra194 chip device tree")

Tegra194 uses separate SDMMC_LEGACY_TM clock for data timeout and
this clock is not enabled currently which is not recommended.

Tegra194 SDMMC advertises 12Mhz as timeout clock frequency in host
capability register.

So, this clock should be kept enabled by SDMMC driver.

Fixes: 5425fb15d8ee ("arm64: tegra: Add Tegra194 chip device tree")
Cc: stable <[email protected]> # 5.4
Tested-by: Jon Hunter <[email protected]>
Reviewed-by: Jon Hunter <[email protected]>
Signed-off-by: Sowjanya Komatineni <[email protected]>
---
arch/arm64/boot/dts/nvidia/tegra194.dtsi | 15 +++++++++------
1 file changed, 9 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/boot/dts/nvidia/tegra194.dtsi b/arch/arm64/boot/dts/nvidia/tegra194.dtsi
index 48160f4..ca5cb6a 100644
--- a/arch/arm64/boot/dts/nvidia/tegra194.dtsi
+++ b/arch/arm64/boot/dts/nvidia/tegra194.dtsi
@@ -460,8 +460,9 @@
compatible = "nvidia,tegra194-sdhci";
reg = <0x03400000 0x10000>;
interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&bpmp TEGRA194_CLK_SDMMC1>;
- clock-names = "sdhci";
+ clocks = <&bpmp TEGRA194_CLK_SDMMC1>,
+ <&bpmp TEGRA194_CLK_SDMMC_LEGACY_TM>;
+ clock-names = "sdhci", "tmclk";
resets = <&bpmp TEGRA194_RESET_SDMMC1>;
reset-names = "sdhci";
interconnects = <&mc TEGRA194_MEMORY_CLIENT_SDMMCRA &emc>,
@@ -485,8 +486,9 @@
compatible = "nvidia,tegra194-sdhci";
reg = <0x03440000 0x10000>;
interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&bpmp TEGRA194_CLK_SDMMC3>;
- clock-names = "sdhci";
+ clocks = <&bpmp TEGRA194_CLK_SDMMC3>,
+ <&bpmp TEGRA194_CLK_SDMMC_LEGACY_TM>;
+ clock-names = "sdhci", "tmclk";
resets = <&bpmp TEGRA194_RESET_SDMMC3>;
reset-names = "sdhci";
interconnects = <&mc TEGRA194_MEMORY_CLIENT_SDMMCR &emc>,
@@ -511,8 +513,9 @@
compatible = "nvidia,tegra194-sdhci";
reg = <0x03460000 0x10000>;
interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&bpmp TEGRA194_CLK_SDMMC4>;
- clock-names = "sdhci";
+ clocks = <&bpmp TEGRA194_CLK_SDMMC4>,
+ <&bpmp TEGRA194_CLK_SDMMC_LEGACY_TM>;
+ clock-names = "sdhci", "tmclk";
assigned-clocks = <&bpmp TEGRA194_CLK_SDMMC4>,
<&bpmp TEGRA194_CLK_PLLC4>;
assigned-clock-parents =
--
2.7.4

2020-08-26 20:09:10

by Sowjanya Komatineni

[permalink] [raw]
Subject: [PATCH v5 3/7] dt-bindings: mmc: tegra: Add tmclk for Tegra210 and later

Tegra210 and later uses separate SDMMC_LEGACY_TM clock for data
timeout.

So, this patch adds "tmclk" to Tegra sdhci clock property in the
device tree binding.

Signed-off-by: Sowjanya Komatineni <[email protected]>
---
.../bindings/mmc/nvidia,tegra20-sdhci.txt | 32 ++++++++++++++++++++--
1 file changed, 29 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/mmc/nvidia,tegra20-sdhci.txt b/Documentation/devicetree/bindings/mmc/nvidia,tegra20-sdhci.txt
index 2cf3aff..96c0b14 100644
--- a/Documentation/devicetree/bindings/mmc/nvidia,tegra20-sdhci.txt
+++ b/Documentation/devicetree/bindings/mmc/nvidia,tegra20-sdhci.txt
@@ -15,8 +15,15 @@ Required properties:
- "nvidia,tegra210-sdhci": for Tegra210
- "nvidia,tegra186-sdhci": for Tegra186
- "nvidia,tegra194-sdhci": for Tegra194
-- clocks : Must contain one entry, for the module clock.
- See ../clocks/clock-bindings.txt for details.
+- clocks: For Tegra210, Tegra186 and Tegra194 must contain two entries.
+ One for the module clock and one for the timeout clock.
+ For all other Tegra devices, must contain a single entry for
+ the module clock. See ../clocks/clock-bindings.txt for details.
+- clock-names: For Tegra210, Tegra186 and Tegra194 must contain the
+ strings 'sdhci' and 'tmclk' to represent the module and
+ the timeout clocks, respectively.
+ For all other Tegra devices must contain the string 'sdhci'
+ to represent the module clock.
- resets : Must contain an entry for each entry in reset-names.
See ../reset/reset.txt for details.
- reset-names : Must include the following entries:
@@ -99,7 +106,7 @@ Optional properties for Tegra210, Tegra186 and Tegra194:

Example:
sdhci@700b0000 {
- compatible = "nvidia,tegra210-sdhci", "nvidia,tegra124-sdhci";
+ compatible = "nvidia,tegra124-sdhci";
reg = <0x0 0x700b0000 0x0 0x200>;
interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&tegra_car TEGRA210_CLK_SDMMC1>;
@@ -115,3 +122,22 @@ sdhci@700b0000 {
nvidia,pad-autocal-pull-down-offset-1v8 = <0x7b>;
status = "disabled";
};
+
+sdhci@700b0000 {
+ compatible = "nvidia,tegra210-sdhci";
+ reg = <0x0 0x700b0000 0x0 0x200>;
+ interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA210_CLK_SDMMC1>,
+ <&tegra_car TEGRA210_CLK_SDMMC_LEGACY>;
+ clock-names = "sdhci", "tmclk";
+ resets = <&tegra_car 14>;
+ reset-names = "sdhci";
+ pinctrl-names = "sdmmc-3v3", "sdmmc-1v8";
+ pinctrl-0 = <&sdmmc1_3v3>;
+ pinctrl-1 = <&sdmmc1_1v8>;
+ nvidia,pad-autocal-pull-up-offset-3v3 = <0x00>;
+ nvidia,pad-autocal-pull-down-offset-3v3 = <0x7d>;
+ nvidia,pad-autocal-pull-up-offset-1v8 = <0x7b>;
+ nvidia,pad-autocal-pull-down-offset-1v8 = <0x7b>;
+ status = "disabled";
+};
--
2.7.4

2020-08-26 20:09:20

by Sowjanya Komatineni

[permalink] [raw]
Subject: [PATCH v5 1/7] sdhci: tegra: Remove SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK for Tegra210

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

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

Tegra210 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 Tegra210.

Fixes: b5a84ecf025a ("mmc: tegra: Add Tegra210 support")
Cc: stable <[email protected]> # 5.4
Tested-by: Jon Hunter <[email protected]>
Reviewed-by: Jon Hunter <[email protected]>
Acked-by: Adrian Hunter <[email protected]>
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 0a3f9d0..2be3511 100644
--- a/drivers/mmc/host/sdhci-tegra.c
+++ b/drivers/mmc/host/sdhci-tegra.c
@@ -1418,7 +1418,6 @@ static const struct sdhci_ops tegra210_sdhci_ops = {

static const struct sdhci_pltfm_data sdhci_tegra210_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-26 20:10:08

by Sowjanya Komatineni

[permalink] [raw]
Subject: [PATCH v5 2/7] 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.

Fixes: 4346b7c7941d ("mmc: tegra: Add Tegra186 support")
Cc: stable <[email protected]> # 5.4
Tested-by: Jon Hunter <[email protected]>
Reviewed-by: Jon Hunter <[email protected]>
Acked-by: Adrian Hunter <[email protected]>
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-27 02:49:07

by kernel test robot

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

Hi Sowjanya,

I love your patch! Yet something to improve:

[auto build test ERROR on robh/for-next]
[also build test ERROR on tegra/for-next v5.9-rc2 next-20200826]
[cannot apply to ulf.hansson-mmc/next]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url: https://github.com/0day-ci/linux/commits/Sowjanya-Komatineni/Fix-timeout-clock-used-by-hardware-data-timeout/20200827-040814
base: https://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git for-next
config: arm-defconfig (attached as .config)
compiler: arm-linux-gnueabi-gcc (GCC) 9.3.0
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=arm

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <[email protected]>

All errors (new ones prefixed by >>):

>> drivers/mmc/host/sdhci-tegra.c:1496:24: error: expected '}' before ';' token
1496 | NVQUIRK_HAS_TMCLK;
| ^
drivers/mmc/host/sdhci-tegra.c:1488:62: note: to match this '{'
1488 | static const struct sdhci_tegra_soc_data soc_data_tegra194 = {
| ^
drivers/mmc/host/sdhci-tegra.c: In function 'sdhci_tegra_probe':
>> drivers/mmc/host/sdhci-tegra.c:1643:6: error: implicit declaration of function 'of_clk_get_parent_count' [-Werror=implicit-function-declaration]
1643 | if (of_clk_get_parent_count(&pdev->dev) == 1) {
| ^~~~~~~~~~~~~~~~~~~~~~~
>> drivers/mmc/host/sdhci-tegra.c:1648:22: error: 'dev' undeclared (first use in this function); did you mean 'pdev'?
1648 | clk = devm_clk_get(dev, NULL)
| ^~~
| pdev
drivers/mmc/host/sdhci-tegra.c:1648:22: note: each undeclared identifier is reported only once for each function it appears in
>> drivers/mmc/host/sdhci-tegra.c:1648:32: error: expected ';' before 'if'
1648 | clk = devm_clk_get(dev, NULL)
| ^
| ;
1649 | if (IS_ERR(clk)) {
| ~~
drivers/mmc/host/sdhci-tegra.c:1682:35: error: expected ';' before 'if'
1682 | clk = devm_clk_get(dev, "sdhci")
| ^
| ;
1683 | if (IS_ERR(clk)) {
| ~~
drivers/mmc/host/sdhci-tegra.c:1727:1: warning: label 'err_clk_get' defined but not used [-Wunused-label]
1727 | err_clk_get:
| ^~~~~~~~~~~
cc1: some warnings being treated as errors

# https://github.com/0day-ci/linux/commit/51ed0e529a10cbce9dba08a11817207acb1b5bcf
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Sowjanya-Komatineni/Fix-timeout-clock-used-by-hardware-data-timeout/20200827-040814
git checkout 51ed0e529a10cbce9dba08a11817207acb1b5bcf
vim +1496 drivers/mmc/host/sdhci-tegra.c

1487
1488 static const struct sdhci_tegra_soc_data soc_data_tegra194 = {
1489 .pdata = &sdhci_tegra186_pdata,
1490 .dma_mask = DMA_BIT_MASK(39),
1491 .nvquirks = NVQUIRK_NEEDS_PAD_CONTROL |
1492 NVQUIRK_HAS_PADCALIB |
1493 NVQUIRK_DIS_CARD_CLK_CONFIG_TAP |
1494 NVQUIRK_ENABLE_SDR50 |
1495 NVQUIRK_ENABLE_SDR104 |
> 1496 NVQUIRK_HAS_TMCLK;
1497 .min_tap_delay = 96,
1498 .max_tap_delay = 139,
1499 };
1500
1501 static const struct of_device_id sdhci_tegra_dt_match[] = {
1502 { .compatible = "nvidia,tegra194-sdhci", .data = &soc_data_tegra194 },
1503 { .compatible = "nvidia,tegra186-sdhci", .data = &soc_data_tegra186 },
1504 { .compatible = "nvidia,tegra210-sdhci", .data = &soc_data_tegra210 },
1505 { .compatible = "nvidia,tegra124-sdhci", .data = &soc_data_tegra124 },
1506 { .compatible = "nvidia,tegra114-sdhci", .data = &soc_data_tegra114 },
1507 { .compatible = "nvidia,tegra30-sdhci", .data = &soc_data_tegra30 },
1508 { .compatible = "nvidia,tegra20-sdhci", .data = &soc_data_tegra20 },
1509 {}
1510 };
1511 MODULE_DEVICE_TABLE(of, sdhci_tegra_dt_match);
1512
1513 static int sdhci_tegra_add_host(struct sdhci_host *host)
1514 {
1515 struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
1516 struct sdhci_tegra *tegra_host = sdhci_pltfm_priv(pltfm_host);
1517 struct cqhci_host *cq_host;
1518 bool dma64;
1519 int ret;
1520
1521 if (!tegra_host->enable_hwcq)
1522 return sdhci_add_host(host);
1523
1524 sdhci_enable_v4_mode(host);
1525
1526 ret = sdhci_setup_host(host);
1527 if (ret)
1528 return ret;
1529
1530 host->mmc->caps2 |= MMC_CAP2_CQE | MMC_CAP2_CQE_DCMD;
1531
1532 cq_host = devm_kzalloc(host->mmc->parent,
1533 sizeof(*cq_host), GFP_KERNEL);
1534 if (!cq_host) {
1535 ret = -ENOMEM;
1536 goto cleanup;
1537 }
1538
1539 cq_host->mmio = host->ioaddr + SDHCI_TEGRA_CQE_BASE_ADDR;
1540 cq_host->ops = &sdhci_tegra_cqhci_ops;
1541
1542 dma64 = host->flags & SDHCI_USE_64_BIT_DMA;
1543 if (dma64)
1544 cq_host->caps |= CQHCI_TASK_DESC_SZ_128;
1545
1546 ret = cqhci_init(cq_host, host->mmc, dma64);
1547 if (ret)
1548 goto cleanup;
1549
1550 ret = __sdhci_add_host(host);
1551 if (ret)
1552 goto cleanup;
1553
1554 return 0;
1555
1556 cleanup:
1557 sdhci_cleanup_host(host);
1558 return ret;
1559 }
1560
1561 static int sdhci_tegra_probe(struct platform_device *pdev)
1562 {
1563 const struct of_device_id *match;
1564 const struct sdhci_tegra_soc_data *soc_data;
1565 struct sdhci_host *host;
1566 struct sdhci_pltfm_host *pltfm_host;
1567 struct sdhci_tegra *tegra_host;
1568 struct clk *clk;
1569 int rc;
1570
1571 match = of_match_device(sdhci_tegra_dt_match, &pdev->dev);
1572 if (!match)
1573 return -EINVAL;
1574 soc_data = match->data;
1575
1576 host = sdhci_pltfm_init(pdev, soc_data->pdata, sizeof(*tegra_host));
1577 if (IS_ERR(host))
1578 return PTR_ERR(host);
1579 pltfm_host = sdhci_priv(host);
1580
1581 tegra_host = sdhci_pltfm_priv(pltfm_host);
1582 tegra_host->ddr_signaling = false;
1583 tegra_host->pad_calib_required = false;
1584 tegra_host->pad_control_available = false;
1585 tegra_host->soc_data = soc_data;
1586
1587 if (soc_data->nvquirks & NVQUIRK_NEEDS_PAD_CONTROL) {
1588 rc = tegra_sdhci_init_pinctrl_info(&pdev->dev, tegra_host);
1589 if (rc == 0)
1590 host->mmc_host_ops.start_signal_voltage_switch =
1591 sdhci_tegra_start_signal_voltage_switch;
1592 }
1593
1594 /* Hook to periodically rerun pad calibration */
1595 if (soc_data->nvquirks & NVQUIRK_HAS_PADCALIB)
1596 host->mmc_host_ops.request = tegra_sdhci_request;
1597
1598 host->mmc_host_ops.hs400_enhanced_strobe =
1599 tegra_sdhci_hs400_enhanced_strobe;
1600
1601 if (!host->ops->platform_execute_tuning)
1602 host->mmc_host_ops.execute_tuning =
1603 tegra_sdhci_execute_hw_tuning;
1604
1605 rc = mmc_of_parse(host->mmc);
1606 if (rc)
1607 goto err_parse_dt;
1608
1609 if (tegra_host->soc_data->nvquirks & NVQUIRK_ENABLE_DDR50)
1610 host->mmc->caps |= MMC_CAP_1_8V_DDR;
1611
1612 /* HW busy detection is supported, but R1B responses are required. */
1613 host->mmc->caps |= MMC_CAP_WAIT_WHILE_BUSY | MMC_CAP_NEED_RSP_BUSY;
1614
1615 tegra_sdhci_parse_dt(host);
1616
1617 tegra_host->power_gpio = devm_gpiod_get_optional(&pdev->dev, "power",
1618 GPIOD_OUT_HIGH);
1619 if (IS_ERR(tegra_host->power_gpio)) {
1620 rc = PTR_ERR(tegra_host->power_gpio);
1621 goto err_power_req;
1622 }
1623
1624 /*
1625 * Tegra210 and later has separate SDMMC_LEGACY_TM clock used for
1626 * hardware data timeout clock and SW can choose TMCLK or SDCLK for
1627 * hardware data timeout through the bit USE_TMCLK_FOR_DATA_TIMEOUT
1628 * of the register SDHCI_TEGRA_VENDOR_SYS_SW_CTRL.
1629 *
1630 * USE_TMCLK_FOR_DATA_TIMEOUT bit default is set to 1 and SDMMC uses
1631 * 12Mhz TMCLK which is advertised in host capability register.
1632 * With TMCLK of 12Mhz provides maximum data timeout period that can
1633 * be achieved is 11s better than using SDCLK for data timeout.
1634 *
1635 * So, TMCLK is set to 12Mhz and kept enabled all the time on SoC's
1636 * supporting separate TMCLK.
1637 *
1638 * Old device tree has single sdhci clock. So with addition of TMCLK,
1639 * retrieving sdhci clock by "sdhci" clock name based on number of
1640 * clocks in sdhci device node.
1641 */
1642
> 1643 if (of_clk_get_parent_count(&pdev->dev) == 1) {
1644 if (soc_data->nvquirks & NVQUIRK_HAS_TMCLK)
1645 dev_warn(&pdev->dev,
1646 "missing tmclk in the device tree\n");
1647
> 1648 clk = devm_clk_get(dev, NULL)
1649 if (IS_ERR(clk)) {
1650 rc = PTR_ERR(clk);
1651
1652 if (rc != -EPROBE_DEFER)
1653 dev_err(&pdev->dev,
1654 "failed to get sdhci clock: %d\n", rc);
1655
1656 goto err_power_req;
1657 }
1658 } else {
1659 if (soc_data->nvquirks & NVQUIRK_HAS_TMCLK) {
1660 clk = devm_clk_get(&pdev->dev, "tmclk");
1661 if (IS_ERR(clk)) {
1662 rc = PTR_ERR(clk);
1663 if (rc == -EPROBE_DEFER)
1664 goto err_power_req;
1665
1666 dev_warn(&pdev->dev,
1667 "failed to get tmclk: %d\n", rc);
1668 clk = NULL;
1669 }
1670
1671 clk_set_rate(clk, 12000000);
1672 rc = clk_prepare_enable(clk);
1673 if (rc) {
1674 dev_err(&pdev->dev,
1675 "failed to enable tmclk: %d\n", rc);
1676 goto err_power_req;
1677 }
1678
1679 tegra_host->tmclk = clk;
1680 }
1681
1682 clk = devm_clk_get(dev, "sdhci")
1683 if (IS_ERR(clk)) {
1684 rc = PTR_ERR(clk);
1685
1686 if (rc != -EPROBE_DEFER)
1687 dev_err(&pdev->dev,
1688 "failed to get sdhci clock: %d\n", rc);
1689
1690 goto err_clk_get;
1691 }
1692 }
1693
1694 clk_prepare_enable(clk);
1695 pltfm_host->clk = clk;
1696
1697 tegra_host->rst = devm_reset_control_get_exclusive(&pdev->dev,
1698 "sdhci");
1699 if (IS_ERR(tegra_host->rst)) {
1700 rc = PTR_ERR(tegra_host->rst);
1701 dev_err(&pdev->dev, "failed to get reset control: %d\n", rc);
1702 goto err_rst_get;
1703 }
1704
1705 rc = reset_control_assert(tegra_host->rst);
1706 if (rc)
1707 goto err_rst_get;
1708
1709 usleep_range(2000, 4000);
1710
1711 rc = reset_control_deassert(tegra_host->rst);
1712 if (rc)
1713 goto err_rst_get;
1714
1715 usleep_range(2000, 4000);
1716
1717 rc = sdhci_tegra_add_host(host);
1718 if (rc)
1719 goto err_add_host;
1720
1721 return 0;
1722
1723 err_add_host:
1724 reset_control_assert(tegra_host->rst);
1725 err_rst_get:
1726 clk_disable_unprepare(pltfm_host->clk);
1727 err_clk_get:
1728 clk_disable_unprepare(tegra_host->tmclk);
1729 err_power_req:
1730 err_parse_dt:
1731 sdhci_pltfm_free(pdev);
1732 return rc;
1733 }
1734

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/[email protected]


Attachments:
(No filename) (11.71 kB)
.config.gz (51.82 kB)
Download all attachments

2020-08-27 03:01:14

by Sowjanya Komatineni

[permalink] [raw]
Subject: Re: [PATCH v5 0/7] Fix timeout clock used by hardware data timeout

Sorry please ignore this series.

Wrong patches from my system went out.

Will send as v6.

Thanks

Sowjanya

On 8/26/20 1:05 PM, Sowjanya Komatineni wrote:
> 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 and 4.19.
>
> Will send patches to backport separately once these patches are ack'd.
>
> Delta between patch versions:
> [v5]: Include below changes based on v4 feedback
> - updated dt-binding doc to be more clear
> - updated Tegra sdhci driver to retrieve sdhci and tmclk clocks
> based on no. of clocks in sdhci device node as old device trees
> do not use sdhci clock name and this allows proper clock retrival
> irrespective of sdhci and tmclk clocks order in device tree.
> - Added separate quirk for identifying SoC's supporting separate
> timeout clock to be more clear.
>
> [v4]: Include additional dt-binding patch
>
> [v3]: Same as v2 with fixes tag
>
> [v2]: Includes minor fix
> - Patch-0006: parentheses around operand of '!'
>
> Sowjanya Komatineni (7):
> sdhci: tegra: Remove SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK for Tegra210
> sdhci: tegra: Remove SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK for Tegra186
> dt-bindings: mmc: tegra: Add tmclk for Tegra210 and later
> 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
>
> .../bindings/mmc/nvidia,tegra20-sdhci.txt | 32 +++++++-
> 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 | 91 +++++++++++++++++++---
> 5 files changed, 143 insertions(+), 35 deletions(-)
>