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

Commit f828656f 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: add dynamic Qos for cpu-dma-latency."

parents bdbb378b d012137d
Loading
Loading
Loading
Loading
+51 −7
Original line number Diff line number Diff line
@@ -310,7 +310,8 @@ struct sdhci_msm_pltfm_data {
	bool pin_cfg_sts;
	struct sdhci_msm_pin_data *pin_data;
	struct sdhci_pinctrl_data *pctrl_data;
	u32 cpu_dma_latency_us;
	u32 *cpu_dma_latency_us;
	unsigned int cpu_dma_latency_tbl_sz;
	int status_gpio; /* card detection GPIO that is configured as IRQ */
	struct sdhci_msm_bus_voting_data *voting_data;
	u32 *sup_clk_table;
@@ -1492,11 +1493,12 @@ static struct sdhci_msm_pltfm_data *sdhci_msm_populate_pdata(struct device *dev)
	struct sdhci_msm_pltfm_data *pdata = NULL;
	struct device_node *np = dev->of_node;
	u32 bus_width = 0;
	u32 cpu_dma_latency;
	u32 prop_val = 0;
	int len, i, mpm_int;
	int clk_table_len;
	u32 *clk_table = NULL;
	enum of_gpio_flags flags = OF_GPIO_ACTIVE_LOW;
	bool skip_qos_from_dt = false;

	pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
	if (!pdata) {
@@ -1518,11 +1520,52 @@ static struct sdhci_msm_pltfm_data *sdhci_msm_populate_pdata(struct device *dev)
		pdata->mmc_bus_width = 0;
	}

	if (!of_property_read_u32(np, "qcom,cpu-dma-latency-us",
				&cpu_dma_latency))
		pdata->cpu_dma_latency_us = cpu_dma_latency;
	else
		pdata->cpu_dma_latency_us = MSM_MMC_DEFAULT_CPU_DMA_LATENCY;
	if (of_get_property(np, "qcom,cpu-dma-latency-us",
				&prop_val)) {

		pdata->cpu_dma_latency_tbl_sz =
			prop_val/sizeof(*pdata->cpu_dma_latency_us);

		if (!(pdata->cpu_dma_latency_tbl_sz == 1 ||
			pdata->cpu_dma_latency_tbl_sz == 3)) {
			dev_warn(dev, "incorrect Qos param passed from DT: %d\n",
				pdata->cpu_dma_latency_tbl_sz);
			skip_qos_from_dt = true;
		} else {
			pdata->cpu_dma_latency_us = devm_kzalloc(dev,
				sizeof(*pdata->cpu_dma_latency_us) *
				pdata->cpu_dma_latency_tbl_sz,
				GFP_KERNEL);
			if (!pdata->cpu_dma_latency_us) {
				dev_err(dev, "No memory for cpu_dma_latency_us\n");
				goto out;
			}
			if (of_property_read_u32_array(np,
					"qcom,cpu-dma-latency-us",
					pdata->cpu_dma_latency_us,
					pdata->cpu_dma_latency_tbl_sz)) {
				dev_err(dev, "failed to parse cpu-dma-latency\n");
				goto out;
			}
		}
	} else {
		dev_info(dev, "no qcom,cpu-dma-latency-us found\n");
		skip_qos_from_dt = true;
	}

	if (skip_qos_from_dt) {
		pdata->cpu_dma_latency_tbl_sz = 1;
		pdata->cpu_dma_latency_us = devm_kzalloc(dev,
			sizeof(*pdata->cpu_dma_latency_us) *
			pdata->cpu_dma_latency_tbl_sz,
			GFP_KERNEL);
		if (!pdata->cpu_dma_latency_us) {
			dev_err(dev, "No memory for cpu_dma_latency_us\n");
			goto out;
		}
		pdata->cpu_dma_latency_us[0] = MSM_MMC_DEFAULT_CPU_DMA_LATENCY;
	}

	if (sdhci_msm_dt_get_array(dev, "qcom,clk-rates",
			&clk_table, &clk_table_len, 0)) {
		dev_err(dev, "failed parsing supported clock rates\n");
@@ -3298,6 +3341,7 @@ static int sdhci_msm_probe(struct platform_device *pdev)
		msm_host->mmc->caps2 |= MMC_CAP2_NONHOTPLUG;

	host->cpu_dma_latency_us = msm_host->pdata->cpu_dma_latency_us;
	host->cpu_dma_latency_tbl_sz = msm_host->pdata->cpu_dma_latency_tbl_sz;
	host->pm_qos_req_dma.type = msm_host->pdata->cpu_affinity_type;
	if (host->pm_qos_req_dma.type == PM_QOS_REQ_AFFINE_CORES)
		bitmap_copy(cpumask_bits(&host->pm_qos_req_dma.cpus_affine),
+32 −19
Original line number Diff line number Diff line
@@ -1511,10 +1511,18 @@ static int sdhci_set_power(struct sdhci_host *host, unsigned short power)
static int sdhci_enable(struct mmc_host *mmc)
{
	struct sdhci_host *host = mmc_priv(mmc);
	u32 pol_index = 0;

	if (unlikely(!host->cpu_dma_latency_us))
		goto platform_bus_vote;

	if (host->cpu_dma_latency_tbl_sz > 1)
		pol_index = host->power_policy;

	if (host->cpu_dma_latency_us)
	pm_qos_update_request(&host->pm_qos_req_dma,
					host->cpu_dma_latency_us);
		host->cpu_dma_latency_us[pol_index]);

platform_bus_vote:
	if (host->ops->platform_bus_voting)
		host->ops->platform_bus_voting(host, 1);

@@ -1524,8 +1532,13 @@ static int sdhci_enable(struct mmc_host *mmc)
static int sdhci_disable(struct mmc_host *mmc)
{
	struct sdhci_host *host = mmc_priv(mmc);
	u32 pol_index = 0;

	if (host->cpu_dma_latency_us) {
	if (unlikely(!host->cpu_dma_latency_us))
		goto platform_bus_vote;

	if (host->cpu_dma_latency_tbl_sz > 1)
		pol_index = host->power_policy;
	/*
	 * In performance mode, release QoS vote after a timeout to
	 * make sure back-to-back requests don't suffer from latencies
@@ -1533,15 +1546,15 @@ static int sdhci_disable(struct mmc_host *mmc)
	 * where the CPU goes into low power mode as soon as QoS vote is
	 * released.
	 */
		if (host->power_policy == SDHCI_PERFORMANCE_MODE)
			pm_qos_update_request_timeout(&host->pm_qos_req_dma,
					host->cpu_dma_latency_us,
					host->pm_qos_timeout_us);
		else
	if (host->power_policy == SDHCI_POWER_SAVE_MODE)
		pm_qos_update_request(&host->pm_qos_req_dma,
			PM_QOS_DEFAULT_VALUE);
	}
	else
		pm_qos_update_request_timeout(&host->pm_qos_req_dma,
			host->cpu_dma_latency_us[pol_index],
			host->pm_qos_timeout_us);

platform_bus_vote:
	if (host->ops->platform_bus_voting)
		host->ops->platform_bus_voting(host, 0);

+2 −1
Original line number Diff line number Diff line
@@ -264,7 +264,8 @@ struct sdhci_host {
#define SDHCI_TUNING_MODE_1	0
	struct timer_list	tuning_timer;	/* Timer for tuning */

	unsigned int cpu_dma_latency_us;
	unsigned int *cpu_dma_latency_us;
	unsigned int cpu_dma_latency_tbl_sz;
	struct pm_qos_request pm_qos_req_dma;
	unsigned int pm_qos_timeout_us;         /* timeout for PM QoS request */
	struct device_attribute pm_qos_tout;