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

Commit 0cbf9aff authored by qctecmdr Service's avatar qctecmdr Service Committed by Gerrit - the friendly Code Review server
Browse files

Merge "mmc: sdhci-msm: Fix the retention of DLL regs from CX Collapse"

parents c0529446 517eb3e9
Loading
Loading
Loading
Loading
+75 −28
Original line number Diff line number Diff line
@@ -365,6 +365,11 @@ enum vdd_io_level {
	VDD_IO_SET_LEVEL,
};

enum dll_init_context {
	DLL_INIT_NORMAL = 0,
	DLL_INIT_FROM_CX_COLLAPSE_EXIT,
};

/* MSM platform specific tuning */
static inline int msm_dll_poll_ck_out_en(struct sdhci_host *host,
						u8 poll)
@@ -709,7 +714,8 @@ static inline void msm_cm_dll_set_freq(struct sdhci_host *host)
}

/* Initialize the DLL (Programmable Delay Line ) */
static int msm_init_cm_dll(struct sdhci_host *host)
static int msm_init_cm_dll(struct sdhci_host *host,
				enum dll_init_context init_context)
{
	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
	struct sdhci_msm_host *msm_host = pltfm_host->priv;
@@ -766,6 +772,14 @@ static int msm_init_cm_dll(struct sdhci_host *host)
	if (msm_host->use_updated_dll_reset) {
		u32 mclk_freq = 0;

		/*
		 * Only configure the mclk_freq in normal DLL init
		 * context. If the DLL init is coming from
		 * CX Collapse Exit context, the host->clock may be zero.
		 * The DLL_CONFIG_2 register has already been restored to
		 * proper value prior to getting here.
		 */
		if (init_context == DLL_INIT_NORMAL) {
			switch (host->clock) {
			case 208000000:
			case 202000000:
@@ -792,6 +806,7 @@ static int msm_init_cm_dll(struct sdhci_host *host)
			   msm_host_offset->CORE_DLL_CONFIG_2)
			   & ~(0xFF << 10)) | (mclk_freq << 10)),
			   host->ioaddr + msm_host_offset->CORE_DLL_CONFIG_2);
		}
		/* wait for 5us before enabling DLL clock */
		udelay(5);
	}
@@ -1075,7 +1090,7 @@ static int sdhci_msm_enhanced_strobe(struct sdhci_host *host)
	/*
	 * Reset the tuning block.
	 */
	ret = msm_init_cm_dll(host);
	ret = msm_init_cm_dll(host, DLL_INIT_NORMAL);
	if (ret)
		goto out;

@@ -1102,7 +1117,7 @@ static int sdhci_msm_hs400_dll_calibration(struct sdhci_host *host)
	 * Retuning in HS400 (DDR mode) will fail, just reset the
	 * tuning block and restore the saved tuning phase.
	 */
	ret = msm_init_cm_dll(host);
	ret = msm_init_cm_dll(host, DLL_INIT_NORMAL);
	if (ret)
		goto out;

@@ -1225,7 +1240,7 @@ int sdhci_msm_execute_tuning(struct sdhci_host *host, u32 opcode)
	tuned_phase_cnt = 0;

	/* first of all reset the tuning block */
	rc = msm_init_cm_dll(host);
	rc = msm_init_cm_dll(host, DLL_INIT_NORMAL);
	if (rc)
		goto kfree;

@@ -3071,6 +3086,19 @@ static void sdhci_msm_registers_save(struct sdhci_host *host)
		sdhci_readl(host, SDHCI_CAPABILITIES_1);
	msm_host->regs_restore.testbus_config = readl_relaxed(host->ioaddr +
		msm_host_offset->CORE_TESTBUS_CONFIG);
	msm_host->regs_restore.dll_config = readl_relaxed(host->ioaddr +
		msm_host_offset->CORE_DLL_CONFIG);
	msm_host->regs_restore.dll_config2 = readl_relaxed(host->ioaddr +
		msm_host_offset->CORE_DLL_CONFIG_2);
	msm_host->regs_restore.dll_config = readl_relaxed(host->ioaddr +
		msm_host_offset->CORE_DLL_CONFIG);
	msm_host->regs_restore.dll_config2 = readl_relaxed(host->ioaddr +
		msm_host_offset->CORE_DLL_CONFIG_2);
	msm_host->regs_restore.dll_config3 = readl_relaxed(host->ioaddr +
		msm_host_offset->CORE_DLL_CONFIG_3);
	msm_host->regs_restore.dll_usr_ctl = readl_relaxed(host->ioaddr +
		msm_host_offset->CORE_DLL_USR_CTL);

	msm_host->regs_restore.is_valid = true;

	pr_debug("%s: %s: registers saved. PWRCTL_MASK = 0x%x\n",
@@ -3086,6 +3114,7 @@ static void sdhci_msm_registers_restore(struct sdhci_host *host)
	u8 irq_status;
	const struct sdhci_msm_offset *msm_host_offset =
					msm_host->offset;
	struct mmc_ios ios = host->mmc->ios;

	if (!msm_host->regs_restore.is_supported ||
		!msm_host->regs_restore.is_valid)
@@ -3137,6 +3166,24 @@ static void sdhci_msm_registers_restore(struct sdhci_host *host)
	writel_relaxed(msm_host->regs_restore.vendor_pwrctl_mask,
			host->ioaddr + msm_host_offset->CORE_PWRCTL_MASK);

	if (((ios.timing == MMC_TIMING_MMC_HS400) ||
			(ios.timing == MMC_TIMING_MMC_HS200) ||
			(ios.timing == MMC_TIMING_UHS_SDR104))
			&& (ios.clock > CORE_FREQ_100MHZ)) {
		writel_relaxed(msm_host->regs_restore.dll_config2,
			host->ioaddr + msm_host_offset->CORE_DLL_CONFIG_2);
		writel_relaxed(msm_host->regs_restore.dll_config3,
			host->ioaddr + msm_host_offset->CORE_DLL_CONFIG_3);
		writel_relaxed(msm_host->regs_restore.dll_usr_ctl,
			host->ioaddr + msm_host_offset->CORE_DLL_USR_CTL);
		writel_relaxed(msm_host->regs_restore.dll_config &
			~(CORE_DLL_RST | CORE_DLL_PDN),
			host->ioaddr + msm_host_offset->CORE_DLL_CONFIG);

		msm_init_cm_dll(host, DLL_INIT_FROM_CX_COLLAPSE_EXIT);
		msm_config_cm_dll_phase(host, msm_host->saved_tuning_phase);
	}

	pr_debug("%s: %s: registers restored. PWRCTL_MASK = 0x%x\n",
		mmc_hostname(host->mmc), __func__,
		readl_relaxed(host->ioaddr +
+4 −0
Original line number Diff line number Diff line
@@ -195,6 +195,10 @@ struct sdhci_msm_regs_restore {
	u32 hc_3c_3e;
	u32 hc_caps_1;
	u32 testbus_config;
	u32 dll_config;
	u32 dll_config2;
	u32 dll_config3;
	u32 dll_usr_ctl;
};

struct sdhci_msm_debug_data {