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

Commit df31535b authored by Venkat Gopalakrishnan's avatar Venkat Gopalakrishnan Committed by Matt Wagantall
Browse files

mmc: sdhci-msm: Update DLL reset sequence



The latest version of the SDCC core requires a change in the reset
sequence for DLL tuning. Make necessary changes as needed.

Change-Id: I69e972c08e89efebff9822de6d0e59692784652e
Signed-off-by: default avatarVenkat Gopalakrishnan <venkatg@codeaurora.org>
parent d5cc07e8
Loading
Loading
Loading
Loading
+48 −0
Original line number Diff line number Diff line
@@ -153,6 +153,8 @@

#define CORE_DLL_CONFIG_2	0x1B4
#define CORE_DDR_CAL_EN		(1 << 0)
#define CORE_FLL_CYCLE_CNT	(1 << 18)
#define CORE_DLL_CLOCK_DISABLE	(1 << 21)

#define CORE_DDR_CONFIG		0x1B8
#define DDR_CONFIG_POR_VAL	0x80040853
@@ -162,6 +164,7 @@
#define SDHCI_MSM_MMC_CLK_GATE_DELAY	200 /* msecs */

#define CORE_FREQ_100MHZ	(100 * 1000 * 1000)
#define TCXO_FREQ		19200000

#define INVALID_TUNING_PHASE	-1

@@ -313,6 +316,7 @@ struct sdhci_msm_host {
	struct device_attribute auto_cmd21_attr;
	atomic_t controller_clock;
	bool use_cdclp533;
	bool use_updated_dll_reset;
};

enum vdd_io_level {
@@ -643,6 +647,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)
{
	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
	struct sdhci_msm_host *msm_host = pltfm_host->priv;
	struct mmc_host *mmc = host->mmc;
	int rc = 0;
	unsigned long flags;
@@ -667,6 +673,17 @@ static int msm_init_cm_dll(struct sdhci_host *host)
		curr_pwrsave = false;
	}

	if (msm_host->use_updated_dll_reset) {
		/* Disable the DLL clock */
		writel_relaxed((readl_relaxed(host->ioaddr + CORE_DLL_CONFIG)
				& ~CORE_CK_OUT_EN),
				host->ioaddr + CORE_DLL_CONFIG);

		writel_relaxed((readl_relaxed(host->ioaddr + CORE_DLL_CONFIG_2)
				| CORE_DLL_CLOCK_DISABLE),
				host->ioaddr + CORE_DLL_CONFIG_2);
	}

	/* Write 1 to DLL_RST bit of DLL_CONFIG register */
	writel_relaxed((readl_relaxed(host->ioaddr + CORE_DLL_CONFIG)
			| CORE_DLL_RST), host->ioaddr + CORE_DLL_CONFIG);
@@ -676,6 +693,22 @@ static int msm_init_cm_dll(struct sdhci_host *host)
			| CORE_DLL_PDN), host->ioaddr + CORE_DLL_CONFIG);
	msm_cm_dll_set_freq(host);

	if (msm_host->use_updated_dll_reset) {
		u32 mclk_freq = 0;

		if ((readl_relaxed(host->ioaddr + CORE_DLL_CONFIG_2)
					& CORE_FLL_CYCLE_CNT))
			mclk_freq = (u32) ((host->clock / TCXO_FREQ) * 8);
		else
			mclk_freq = (u32) ((host->clock / TCXO_FREQ) * 4);

		writel_relaxed(((readl_relaxed(host->ioaddr + CORE_DLL_CONFIG_2)
				& ~(0xFF << 10)) | (mclk_freq << 10)),
				host->ioaddr + CORE_DLL_CONFIG_2);
		/* wait for 5us before enabling DLL clock */
		udelay(5);
	}

	/* Write 0 to DLL_RST bit of DLL_CONFIG register */
	writel_relaxed((readl_relaxed(host->ioaddr + CORE_DLL_CONFIG)
			& ~CORE_DLL_RST), host->ioaddr + CORE_DLL_CONFIG);
@@ -684,6 +717,14 @@ static int msm_init_cm_dll(struct sdhci_host *host)
	writel_relaxed((readl_relaxed(host->ioaddr + CORE_DLL_CONFIG)
			& ~CORE_DLL_PDN), host->ioaddr + CORE_DLL_CONFIG);

	if (msm_host->use_updated_dll_reset) {
		msm_cm_dll_set_freq(host);
		/* Enable the DLL clock */
		writel_relaxed((readl_relaxed(host->ioaddr + CORE_DLL_CONFIG_2)
				& ~CORE_DLL_CLOCK_DISABLE),
				host->ioaddr + CORE_DLL_CONFIG_2);
	}

	/* Set DLL_EN bit to 1. */
	writel_relaxed((readl_relaxed(host->ioaddr + CORE_DLL_CONFIG)
			| CORE_DLL_EN), host->ioaddr + CORE_DLL_CONFIG);
@@ -2814,6 +2855,13 @@ static void sdhci_set_default_hw_caps(struct sdhci_msm_host *msm_host,
	if ((major == 1) && (minor < 0x34))
		msm_host->use_cdclp533 = true;

	/*
	 * SDCC 5 controller with major version 1, minor version 0x42 and later
	 * will require additional steps when resetting DLL.
	 */
	if ((major == 1) && (minor >= 0x42))
		msm_host->use_updated_dll_reset = true;

	/*
	 * Mask 64-bit support for controller with 32-bit address bus so that
	 * smaller descriptor size will be used and improve memory consumption.