mirror of
https://github.com/armbian/build
synced 2025-09-24 19:47:06 +07:00
100 lines
3.1 KiB
Diff
100 lines
3.1 KiB
Diff
From 10c0d24c9ab36e166b717bc89a0c0d7ec668c978 Mon Sep 17 00:00:00 2001
|
|
From: Ram Prakash Gupta <quic_rampraka@quicinc.com>
|
|
Date: Tue, 22 Oct 2024 16:40:25 +0530
|
|
Subject: [PATCH] mmc: sdhci-msm: Toggle the FIFO write clock after ungate
|
|
|
|
For Qualcomm SoCs with sdcc minor version 6B and more, command path
|
|
state machine is getting corrupted post clock ungate which is leading
|
|
to software timeout.
|
|
|
|
Toggle the write fifo clock to reset the async fifo to fix this issue.
|
|
|
|
Signed-off-by: Ram Prakash Gupta <quic_rampraka@quicinc.com>
|
|
---
|
|
drivers/mmc/host/sdhci-msm.c | 41 ++++++++++++++++++++++++++++++++++++
|
|
1 file changed, 41 insertions(+)
|
|
|
|
diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c
|
|
index 9473039ccb13..b3643aec5444 100644
|
|
--- a/drivers/mmc/host/sdhci-msm.c
|
|
+++ b/drivers/mmc/host/sdhci-msm.c
|
|
@@ -158,6 +158,7 @@
|
|
/* CQHCI vendor specific registers */
|
|
#define CQHCI_VENDOR_CFG1 0xA00
|
|
#define CQHCI_VENDOR_DIS_RST_ON_CQ_EN (0x3 << 13)
|
|
+#define RCLK_TOGGLE BIT(1)
|
|
|
|
struct sdhci_msm_offset {
|
|
u32 core_hc_mode;
|
|
@@ -303,6 +304,7 @@ struct sdhci_msm_host {
|
|
u32 dll_config;
|
|
u32 ddr_config;
|
|
bool vqmmc_enabled;
|
|
+ bool toggle_fifo_clk;
|
|
};
|
|
|
|
static const struct sdhci_msm_offset *sdhci_priv_msm_offset(struct sdhci_host *host)
|
|
@@ -1184,6 +1186,39 @@ static int sdhci_msm_restore_sdr_dll_config(struct sdhci_host *host)
|
|
return ret;
|
|
}
|
|
|
|
+/*
|
|
+ * After MCLK ugating, toggle the FIFO write clock to get
|
|
+ * the FIFO pointers and flags to valid state.
|
|
+ */
|
|
+static void sdhci_msm_toggle_fifo_write_clk(struct sdhci_host *host)
|
|
+{
|
|
+ u32 config;
|
|
+ struct mmc_ios ios = host->mmc->ios;
|
|
+ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
|
|
+ struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host);
|
|
+ const struct sdhci_msm_offset *msm_offset = msm_host->offset;
|
|
+
|
|
+ if ((msm_host->tuning_done || ios.enhanced_strobe) &&
|
|
+ host->mmc->ios.timing == MMC_TIMING_MMC_HS400) {
|
|
+ /*
|
|
+ * Select MCLK as DLL input clock.
|
|
+ */
|
|
+ config = readl_relaxed(host->ioaddr + msm_offset->core_dll_config_3);
|
|
+ config |= RCLK_TOGGLE;
|
|
+ writel_relaxed(config, host->ioaddr + msm_offset->core_dll_config_3);
|
|
+
|
|
+ /* ensure above write as toggling same bit quickly */
|
|
+ wmb();
|
|
+ udelay(2);
|
|
+
|
|
+ /*
|
|
+ * Select RCLK as DLL input clock
|
|
+ */
|
|
+ config &= ~RCLK_TOGGLE;
|
|
+ writel_relaxed(config, host->ioaddr + msm_offset->core_dll_config_3);
|
|
+ }
|
|
+}
|
|
+
|
|
static void sdhci_msm_set_cdr(struct sdhci_host *host, bool enable)
|
|
{
|
|
const struct sdhci_msm_offset *msm_offset = sdhci_priv_msm_offset(host);
|
|
@@ -2662,6 +2697,9 @@ static int sdhci_msm_probe(struct platform_device *pdev)
|
|
if (core_major == 1 && core_minor >= 0x71)
|
|
msm_host->uses_tassadar_dll = true;
|
|
|
|
+ if (core_major == 1 && core_minor >= 0x6B)
|
|
+ msm_host->toggle_fifo_clk = true;
|
|
+
|
|
ret = sdhci_msm_register_vreg(msm_host);
|
|
if (ret)
|
|
goto clk_disable;
|
|
@@ -2795,6 +2833,9 @@ static __maybe_unused int sdhci_msm_runtime_resume(struct device *dev)
|
|
msm_host->bulk_clks);
|
|
if (ret)
|
|
return ret;
|
|
+
|
|
+ if (msm_host->toggle_fifo_clk)
|
|
+ sdhci_msm_toggle_fifo_write_clk(host);
|
|
/*
|
|
* Whenever core-clock is gated dynamically, it's needed to
|
|
* restore the SDR DLL settings when the clock is ungated.
|
|
--
|
|
2.34.1
|
|
|