FAILED: patch "[PATCH] sdhci: tegra: Add missing TMCLK for data timeout" failed to apply to 4.14-stable tree
Subsystems (4)
[email protected]
maintainerThe patch below does not apply to the 4.14-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 8048822bac01936fda2c7b924a52131da81e6198 Mon Sep 17 00:00:00 2001
From: Sowjanya Komatineni <[email protected]>
Date: Thu, 27 Aug 2020 10:21:01 -0700
Subject: [PATCH] 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.
drivers/mmc/host/sdhci-tegra.c +51 -2
@@ -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,6 +1621,43 @@ 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 separate TMCLK. +*/ + +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 (mmc_dev (host->mmc),NULL );if (IS_ERR (clk)) { rc =PTR_ERR (clk);
@@ -1654,6 +1701,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 +1719,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);