From patchwork Tue Sep 1 16:24:50 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sowjanya Komatineni X-Patchwork-Id: 11749067 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 9EDDE13B6 for ; Tue, 1 Sep 2020 16:26:09 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 86B8420767 for ; Tue, 1 Sep 2020 16:26:09 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=nvidia.com header.i=@nvidia.com header.b="B86HxzgL" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731966AbgIAQZ3 (ORCPT ); Tue, 1 Sep 2020 12:25:29 -0400 Received: from hqnvemgate25.nvidia.com ([216.228.121.64]:12031 "EHLO hqnvemgate25.nvidia.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730481AbgIAQZZ (ORCPT ); Tue, 1 Sep 2020 12:25:25 -0400 Received: from hqpgpgate101.nvidia.com (Not Verified[216.228.121.13]) by hqnvemgate25.nvidia.com (using TLS: TLSv1.2, DES-CBC3-SHA) id ; Tue, 01 Sep 2020 09:24:39 -0700 Received: from hqmail.nvidia.com ([172.20.161.6]) by hqpgpgate101.nvidia.com (PGP Universal service); Tue, 01 Sep 2020 09:25:25 -0700 X-PGP-Universal: processed; by hqpgpgate101.nvidia.com on Tue, 01 Sep 2020 09:25:25 -0700 Received: from HQMAIL109.nvidia.com (172.20.187.15) by HQMAIL109.nvidia.com (172.20.187.15) with Microsoft SMTP Server (TLS) id 15.0.1473.3; Tue, 1 Sep 2020 16:25:21 +0000 Received: from rnnvemgw01.nvidia.com (10.128.109.123) by HQMAIL109.nvidia.com (172.20.187.15) with Microsoft SMTP Server (TLS) id 15.0.1473.3 via Frontend Transport; Tue, 1 Sep 2020 16:25:21 +0000 Received: from skomatineni-linux.nvidia.com (Not Verified[10.2.173.243]) by rnnvemgw01.nvidia.com with Trustwave SEG (v7,5,8,10121) id ; Tue, 01 Sep 2020 09:25:21 -0700 From: Sowjanya Komatineni To: , , , , CC: , , , , , Subject: [PATCH v2 4.19 7/7] sdhci: tegra: Add missing TMCLK for data timeout Date: Tue, 1 Sep 2020 09:24:50 -0700 Message-ID: <1598977490-1826-8-git-send-email-skomatineni@nvidia.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1598977490-1826-1-git-send-email-skomatineni@nvidia.com> References: <1598977490-1826-1-git-send-email-skomatineni@nvidia.com> X-NVConfidentiality: public MIME-Version: 1.0 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nvidia.com; s=n1; t=1598977479; bh=tsGv/QEK6JayM8IhEvot3XxT3ByrelWJO4o4XijyBto=; h=X-PGP-Universal:From:To:CC:Subject:Date:Message-ID:X-Mailer: In-Reply-To:References:X-NVConfidentiality:MIME-Version: Content-Type; b=B86HxzgLywlbVwVUo7p+hGWDhrCDMjBunCExV4rGolhVKoZJejE7e7MvFKchc4sDt f//CECGuINDmO9Q/Y1BVKHMZKmZdo1P0uGG8jcg7yNIli5HpbX52q6CIYgBfxsrNOW 9BUec03ujpSZyBCsWsuq74eNiQR50dPHHezjnNapgstP4KoZE2RHpFGCrHUOkcLVry tvDkmNuSMnMrDSLs1WkmKZZhpXAzIzsRJBAd/2h9tN/GFgnb+O1Z+1aFaI42uFFOEU 86y8+3r52S4xcITR2qNysQ5Ch958rolUAlweytXegvi8YoSSnXxj3rEBsq19O0/67x oAT3UexRJ7gwQ== Sender: linux-mmc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org 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. Enabling TMCLK was missed when Tegra210 support was added to the driver in commit b5a84ecf025a ("mmc: tegra: Add Tegra210 support"), 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 # 4.19 Tested-by: Jon Hunter Reviewed-by: Jon Hunter Acked-by: Adrian Hunter Signed-off-by: Sowjanya Komatineni --- drivers/mmc/host/sdhci-tegra.c | 48 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c index 5a7c032..ff3340c 100644 --- a/drivers/mmc/host/sdhci-tegra.c +++ b/drivers/mmc/host/sdhci-tegra.c @@ -56,6 +56,12 @@ #define NVQUIRK_ENABLE_DDR50 BIT(5) #define NVQUIRK_HAS_PADCALIB BIT(6) +/* + * NVQUIRK_HAS_TMCLK is for SoC's having separate timeout clock for Tegra + * SDMMC hardware data timeout. + */ +#define NVQUIRK_HAS_TMCLK BIT(10) + struct sdhci_tegra_soc_data { const struct sdhci_pltfm_data *pdata; u32 nvquirks; @@ -64,6 +70,7 @@ struct sdhci_tegra_soc_data { 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; @@ -433,6 +440,7 @@ 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_HAS_TMCLK, }; static const struct sdhci_pltfm_data sdhci_tegra186_pdata = { @@ -455,6 +463,7 @@ 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_HAS_TMCLK, }; static const struct of_device_id sdhci_tegra_dt_match[] = { @@ -510,6 +519,43 @@ static int sdhci_tegra_probe(struct platform_device *pdev) goto err_power_req; } + /* + * Some Tegra SoC's has a separate SDMMC_LEGACY_TM clock used for + * host 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. + */ + + 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)) { dev_err(mmc_dev(host->mmc), "clk err\n"); @@ -550,6 +596,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); @@ -567,6 +614,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);