Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 65c33bed authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "mmc: sdhci-msm: Implement reset workaround and enable it"

parents eccf6c79 20073c50
Loading
Loading
Loading
Loading
+46 −0
Original line number Diff line number Diff line
@@ -119,6 +119,8 @@
#define CORE_VENDOR_SPEC_ADMA_ERR_ADDR1	0x118

#define CORE_VENDOR_SPEC_FUNC2 0x110
#define HC_SW_RST_WAIT_IDLE_DIS	(1 << 20)
#define HC_SW_RST_REQ (1 << 21)
#define CORE_ONE_MID_EN     (1 << 25)

#define CORE_VENDOR_SPEC_CAPABILITIES0	0x11C
@@ -2967,6 +2969,48 @@ int sdhci_msm_notify_load(struct sdhci_host *host, enum mmc_load state)
	return 0;
}

void sdhci_msm_reset_workaround(struct sdhci_host *host, u32 enable)
{
	u32 vendor_func2;
	unsigned long timeout;

	vendor_func2 = readl_relaxed(host->ioaddr + CORE_VENDOR_SPEC_FUNC2);

	if (enable) {
		writel_relaxed(vendor_func2 | HC_SW_RST_REQ, host->ioaddr +
				CORE_VENDOR_SPEC_FUNC2);
		timeout = 10000;
		while (readl_relaxed(host->ioaddr + CORE_VENDOR_SPEC_FUNC2) &
				HC_SW_RST_REQ) {
			if (timeout == 0) {
				pr_info("%s: Applying wait idle disable workaround\n",
					mmc_hostname(host->mmc));
				/*
				 * Apply the reset workaround to not wait for
				 * pending data transfers on AXI before
				 * resetting the controller. This could be
				 * risky if the transfers were stuck on the
				 * AXI bus.
				 */
				vendor_func2 = readl_relaxed(host->ioaddr +
						CORE_VENDOR_SPEC_FUNC2);
				writel_relaxed(vendor_func2 |
					HC_SW_RST_WAIT_IDLE_DIS,
					host->ioaddr + CORE_VENDOR_SPEC_FUNC2);
				host->reset_wa_t = ktime_get();
				return;
			}
			timeout--;
			udelay(10);
		}
		pr_info("%s: waiting for SW_RST_REQ is successful\n",
				mmc_hostname(host->mmc));
	} else {
		writel_relaxed(vendor_func2 & ~HC_SW_RST_WAIT_IDLE_DIS,
				host->ioaddr + CORE_VENDOR_SPEC_FUNC2);
	}
}

static struct sdhci_ops sdhci_msm_ops = {
	.crypto_engine_cfg = sdhci_msm_ice_cfg,
	.crypto_engine_reset = sdhci_msm_ice_reset,
@@ -2988,6 +3032,7 @@ static struct sdhci_ops sdhci_msm_ops = {
	.enhanced_strobe_mask = sdhci_msm_enhanced_strobe_mask,
	.detect = sdhci_msm_detect,
	.notify_load = sdhci_msm_notify_load,
	.reset_workaround = sdhci_msm_reset_workaround,
};

static void sdhci_set_default_hw_caps(struct sdhci_msm_host *msm_host,
@@ -3030,6 +3075,7 @@ static void sdhci_set_default_hw_caps(struct sdhci_msm_host *msm_host,
	 * on 8992 (minor 0x3e) as a workaround to reset for data stuck issue.
	 */
	if (major == 1 && (minor == 0x2e || minor == 0x3e)) {
		host->quirks2 |= SDHCI_QUIRK2_USE_RESET_WORKAROUND;
		val = readl_relaxed(host->ioaddr + CORE_VENDOR_SPEC_FUNC2);
		writel_relaxed((val | CORE_ONE_MID_EN),
			host->ioaddr + CORE_VENDOR_SPEC_FUNC2);