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

Commit 0c2baf44 authored by Bao D. Nguyen's avatar Bao D. Nguyen
Browse files

mmc: sdhci-msm: Support for getting DLL HSR values from dt file



This is a porting of commit <d44b7d92b3>.
Add support for getting dll hsr setting from device tree file and
to update the dll registers with these HSR settings.

HSR(Hardware Settings Reference) values of DLL specific registers in
SDHC controller would vary based on the process node. Getting these
values through device tree ensure the driver is agnostic of process
node changes.

Use actual clock instead of standard clock rate while configuring DLL
frequency. Otherwise, DLL frequency doesn't match with recommended
HSR value.

With this changes DDR config dt property redundant. So deleting it.

Change-Id: I1e8e1b673c91c2229b979b7a59d89bb5f79ed1cc
Signed-off-by: default avatarBao D. Nguyen <nguyenb@codeaurora.org>
parent c5f2c844
Loading
Loading
Loading
Loading
+82 −28
Original line number Diff line number Diff line
@@ -354,6 +354,9 @@ enum dll_init_context {
	DLL_INIT_FROM_CX_COLLAPSE_EXIT,
};

static unsigned int sdhci_msm_get_sup_clk_rate(struct sdhci_host *host,
						u32 req_clk);

/* MSM platform specific tuning */
static inline int msm_dll_poll_ck_out_en(struct sdhci_host *host,
						u8 poll)
@@ -755,6 +758,7 @@ static int msm_init_cm_dll(struct sdhci_host *host,

	if (msm_host->use_updated_dll_reset) {
		u32 mclk_freq = 0;
		u32 actual_clk = sdhci_msm_get_sup_clk_rate(host, host->clock);

		/*
		 * Only configure the mclk_freq in normal DLL init
@@ -764,7 +768,7 @@ static int msm_init_cm_dll(struct sdhci_host *host,
		 * proper value prior to getting here.
		 */
		if (init_context == DLL_INIT_NORMAL) {
			switch (host->clock) {
			switch (actual_clk) {
			case 208000000:
			case 202000000:
			case 201500000:
@@ -775,10 +779,9 @@ static int msm_init_cm_dll(struct sdhci_host *host,
				mclk_freq = 40;
				break;
			default:
				pr_err("%s: %s: Error. Unsupported clk freq\n",
					mmc_hostname(mmc), __func__);
				rc = -EINVAL;
				goto out;
				mclk_freq = (u32)((actual_clk / TCXO_FREQ) * 4);
				pr_info_once("%s: %s: Non standard clk freq =%u\n",
				mmc_hostname(mmc), __func__, actual_clk);
			}

			if ((readl_relaxed(host->ioaddr +
@@ -815,13 +818,34 @@ static int msm_init_cm_dll(struct sdhci_host *host,

	/* Configure Tassadar DLL (Only applicable for 7FF projects) */
	if (msm_host->use_7nm_dll) {
		if (msm_host->dll_hsr) {
			writel_relaxed(msm_host->dll_hsr->dll_usr_ctl,
					host->ioaddr +
					msm_host_offset->CORE_DLL_USR_CTL);
			writel_relaxed(msm_host->dll_hsr->dll_config_3,
					host->ioaddr +
					msm_host_offset->CORE_DLL_CONFIG_3);
		} else {
			writel_relaxed(DLL_USR_CTL_POR_VAL | FINE_TUNE_MODE_EN |
			ENABLE_DLL_LOCK_STATUS | BIAS_OK_SIGNAL, host->ioaddr +
					ENABLE_DLL_LOCK_STATUS | BIAS_OK_SIGNAL,
					host->ioaddr +
					msm_host_offset->CORE_DLL_USR_CTL);

			writel_relaxed(DLL_CONFIG_3_POR_VAL, host->ioaddr +
				msm_host_offset->CORE_DLL_CONFIG_3);
		}
	}

	/*
	 * Update the lower two bytes of DLL_CONFIG only with HSR values.
	 * Since these are the static settings.
	 */
	if (msm_host->dll_hsr) {
		writel_relaxed((readl_relaxed(host->ioaddr +
			msm_host_offset->CORE_DLL_CONFIG) |
			(msm_host->dll_hsr->dll_config & 0xffff)),
			host->ioaddr + msm_host_offset->CORE_DLL_CONFIG);
	}

	/* Set DLL_EN bit to 1. */
	writel_relaxed((readl_relaxed(host->ioaddr +
@@ -1003,8 +1027,8 @@ static int sdhci_msm_cm_dll_sdc4_calibration(struct sdhci_host *host)
	 * Reprogramming the value in case it might have been modified by
	 * bootloaders.
	 */
	if (msm_host->pdata->rclk_wa) {
		writel_relaxed(msm_host->pdata->ddr_config, host->ioaddr +
	if (msm_host->dll_hsr && msm_host->dll_hsr->ddr_config) {
		writel_relaxed(msm_host->dll_hsr->ddr_config, host->ioaddr +
			msm_host_offset->CORE_DDR_CONFIG);
	} else if (msm_host->rclk_delay_fix) {
		writel_relaxed(DDR_CONFIG_POR_VAL, host->ioaddr +
@@ -1948,6 +1972,34 @@ static void sdhci_msm_pm_qos_parse(struct device *dev,
	}
}

static int sdhci_msm_dt_parse_hsr_info(struct device *dev,
		struct sdhci_msm_host *msm_host)

{
	u32 *dll_hsr_table = NULL;
	int dll_hsr_table_len, dll_hsr_reg_count;
	int ret = 0;

	if (sdhci_msm_dt_get_array(dev, "qcom,dll-hsr-list",
			&dll_hsr_table, &dll_hsr_table_len, 0))
		goto skip_hsr;

	dll_hsr_reg_count = sizeof(struct sdhci_msm_dll_hsr) / sizeof(u32);
	if (dll_hsr_table_len != dll_hsr_reg_count) {
		dev_err(dev, "Number of HSR entries are not matching\n");
		ret = -EINVAL;
	} else {
		msm_host->dll_hsr = (struct sdhci_msm_dll_hsr *)dll_hsr_table;
	}

skip_hsr:
	if (!msm_host->dll_hsr)
		dev_info(dev, "Failed to get dll hsr settings from dt\n");
	if (dll_hsr_table)
		devm_kfree(dev, dll_hsr_table);
	return ret;
}

/* Parse platform data */
static
struct sdhci_msm_pltfm_data *sdhci_msm_populate_pdata(struct device *dev,
@@ -2116,8 +2168,8 @@ struct sdhci_msm_pltfm_data *sdhci_msm_populate_pdata(struct device *dev,
	msm_host->regs_restore.is_supported =
		of_property_read_bool(np, "qcom,restore-after-cx-collapse");

	if (!of_property_read_u32(np, "qcom,ddr-config", &pdata->ddr_config))
		pdata->rclk_wa = true;
	if (sdhci_msm_dt_parse_hsr_info(dev, msm_host))
		goto out;

	return pdata;
out:
@@ -3742,32 +3794,34 @@ void sdhci_msm_dump_vendor_regs(struct sdhci_host *host)
			msm_host_offset->CORE_MCI_FIFO_CNT),
		sdhci_msm_readl_relaxed(host,
			msm_host_offset->CORE_MCI_STATUS));
	pr_info("DLL cfg:  0x%08x | DLL sts:  0x%08x | SDCC ver: 0x%08x\n",
	pr_info("DLL sts: 0x%08x | DLL cfg:  0x%08x | DLL cfg2: 0x%08x\n",
		readl_relaxed(host->ioaddr +
			msm_host_offset->CORE_DLL_STATUS),
		readl_relaxed(host->ioaddr +
			msm_host_offset->CORE_DLL_CONFIG),
		sdhci_msm_readl_relaxed(host,
			msm_host_offset->CORE_DLL_CONFIG_2));
	pr_info("DLL cfg3: 0x%08x | DLL usr ctl:  0x%08x | DDR cfg: 0x%08x\n",
		readl_relaxed(host->ioaddr +
			msm_host_offset->CORE_DLL_STATUS),
			msm_host_offset->CORE_DLL_CONFIG_3),
		readl_relaxed(host->ioaddr +
			msm_host_offset->CORE_DLL_USR_CTL),
		sdhci_msm_readl_relaxed(host,
			msm_host_offset->CORE_MCI_VERSION));
	pr_info("Vndr func: 0x%08x | Vndr adma err : addr0: 0x%08x addr1: 0x%08x\n",
			msm_host_offset->CORE_DDR_CONFIG));
	pr_info("SDCC ver: 0x%08x | Vndr adma err : addr0: 0x%08x addr1: 0x%08x\n",
		readl_relaxed(host->ioaddr +
			msm_host_offset->CORE_VENDOR_SPEC),
			msm_host_offset->CORE_MCI_VERSION),
		readl_relaxed(host->ioaddr +
			msm_host_offset->CORE_VENDOR_SPEC_ADMA_ERR_ADDR0),
		readl_relaxed(host->ioaddr +
			msm_host_offset->CORE_VENDOR_SPEC_ADMA_ERR_ADDR1));
	pr_info("Vndr func2: 0x%08x | dll_config_2: 0x%08x\n",
		readl_relaxed(host->ioaddr +
			msm_host_offset->CORE_VENDOR_SPEC_FUNC2),
	pr_info("Vndr func: 0x%08x | Vndr func2 : 0x%08x Vndr func3: 0x%08x\n",
		readl_relaxed(host->ioaddr +
			msm_host_offset->CORE_DLL_CONFIG_2));
	pr_info("dll_config_3: 0x%08x | ddr_config: 0x%08x |  dll_usr_ctl: 0x%08x\n",
		readl_relaxed(host->ioaddr +
			msm_host_offset->CORE_DLL_CONFIG_3),
			msm_host_offset->CORE_VENDOR_SPEC),
		readl_relaxed(host->ioaddr +
			msm_host_offset->CORE_DDR_CONFIG),
			msm_host_offset->CORE_VENDOR_SPEC_FUNC2),
		readl_relaxed(host->ioaddr +
			msm_host_offset->CORE_DLL_USR_CTL));
			msm_host_offset->CORE_VENDOR_SPEC3));
	/*
	 * tbsel indicates [2:0] bits and tbsel2 indicates [7:4] bits
	 * of CORE_TESTBUS_CONFIG register.
+14 −2
Original line number Diff line number Diff line
@@ -147,8 +147,6 @@ struct sdhci_msm_pltfm_data {
	struct sdhci_msm_pm_qos_data pm_qos_data;
	u32 ice_clk_max;
	u32 ice_clk_min;
	u32 ddr_config;
	bool rclk_wa;
	u32 *bus_clk_table;
	unsigned char bus_clk_cnt;
};
@@ -191,6 +189,19 @@ struct sdhci_msm_regs_restore {
	u32 dll_usr_ctl;
};

/*
 * DLL registers which needs be programmed with HSR settings.
 * Add any new register only at the end and don't change the
 * sequence.
 */
struct sdhci_msm_dll_hsr {
	u32 dll_config;
	u32 dll_config_2;
	u32 dll_config_3;
	u32 dll_usr_ctl;
	u32 ddr_config;
};

struct sdhci_msm_debug_data {
	struct mmc_host copy_mmc;
	struct mmc_card copy_card;
@@ -254,6 +265,7 @@ struct sdhci_msm_host {
	struct workqueue_struct *pm_qos_wq;
	bool use_cdr;
	u32 transfer_mode;
	struct sdhci_msm_dll_hsr *dll_hsr;
};

extern char *saved_command_line;