mmc: host: sdhci: allow definition of pm QoS via dts file

Add a new dts entry to define the CPU affinity in order to maintain
the IRQ pm_qos (Quality of Service) for targets that don't have little
cluster and allow setting the pm_qos to the little cluster,
to improve its performance.

Change-Id: Icf6125066d96331392d98a387974e54c96553306
Signed-off-by: Vince Leung <vincentl@codeaurora.org>
Signed-off-by: Maya Erez <merez@codeaurora.org>
This commit is contained in:
Maya Erez 2014-10-21 20:22:04 +03:00 committed by Subhash Jadavani
parent 7cda2fabdb
commit e5bd1357a1
3 changed files with 48 additions and 3 deletions

View file

@ -60,6 +60,19 @@ In the following, <supply> can be vdd (flash core voltage) or vdd-io (I/O voltag
- pinctrl-names
- pinctrl-0, pinctrl-1,.. pinctrl-n
- qcom,cpu-affinity: this is a string that specifies the pm QoS request
type. The supported cpu affinity modes are :
"all_cores" - PM_QOS_REQ_ALL_CORES is applicable to all CPU cores that
are online and this would have a power impact when there are more
number of CPUs.
"affine_irq" - PM_QOS_REQ_AFFINE_IRQ request type shall update/apply
the vote only to that CPU to which this IRQ's affinity is set to.
"affine_cores" - PM_QOS_REQ_AFFINE_CORES request type is used for
targets that have little cluster and will update/apply the vote to
all the cores in the little cluster.
The default CPU affinity mode is PM_QOS_REQ_AFFINE_IRQ to maintain
backward compatibility.
Example:
aliases {

View file

@ -266,6 +266,7 @@ struct sdhci_msm_pltfm_data {
struct sdhci_msm_bus_voting_data *voting_data;
u32 *sup_clk_table;
unsigned char sup_clk_cnt;
enum pm_qos_req_type cpu_affinity_type;
};
struct sdhci_msm_bus_vote {
@ -1402,6 +1403,30 @@ out:
return ret;
}
#ifdef CONFIG_SMP
static void sdhci_msm_populate_affinity_type(struct sdhci_msm_pltfm_data *pdata,
struct device_node *np)
{
const char *cpu_affinity = NULL;
pdata->cpu_affinity_type = PM_QOS_REQ_AFFINE_IRQ;
if (!of_property_read_string(np, "qcom,cpu-affinity",
&cpu_affinity)) {
if (!strcmp(cpu_affinity, "all_cores"))
pdata->cpu_affinity_type = PM_QOS_REQ_ALL_CORES;
else if (!strcmp(cpu_affinity, "affine_cores"))
pdata->cpu_affinity_type = PM_QOS_REQ_AFFINE_CORES;
else if (!strcmp(cpu_affinity, "affine_irq"))
pdata->cpu_affinity_type = PM_QOS_REQ_AFFINE_IRQ;
}
}
#else
static void sdhci_msm_populate_affinity_type(struct sdhci_msm_pltfm_data *pdata,
struct device_node *np)
{
}
#endif
/* Parse platform data */
static struct sdhci_msm_pltfm_data *sdhci_msm_populate_pdata(struct device *dev)
{
@ -1508,6 +1533,8 @@ static struct sdhci_msm_pltfm_data *sdhci_msm_populate_pdata(struct device *dev)
if (of_get_property(np, "qcom,nonhotplug", NULL))
pdata->nonhotplug = true;
sdhci_msm_populate_affinity_type(pdata, np);
return pdata;
out:
return NULL;
@ -3061,6 +3088,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->pm_qos_req_dma.type = msm_host->pdata->cpu_affinity_type;
init_completion(&msm_host->pwr_irq_completion);

View file

@ -3218,7 +3218,6 @@ EXPORT_SYMBOL_GPL(sdhci_alloc_host);
#ifdef CONFIG_SMP
static void sdhci_set_pmqos_req_type(struct sdhci_host *host)
{
/*
* The default request type PM_QOS_REQ_ALL_CORES is
* applicable to all CPU cores that are online and
@ -3226,9 +3225,14 @@ static void sdhci_set_pmqos_req_type(struct sdhci_host *host)
* number of CPUs. This new PM_QOS_REQ_AFFINE_IRQ request
* type shall update/apply the vote only to that CPU to
* which this IRQ's affinity is set to.
* PM_QOS_REQ_AFFINE_CORES request type is used for targets that have
* little cluster and will update/apply the vote to all the cores in
* the little cluster.
*/
host->pm_qos_req_dma.type = PM_QOS_REQ_AFFINE_IRQ;
host->pm_qos_req_dma.irq = host->irq;
if (host->pm_qos_req_dma.type == PM_QOS_REQ_AFFINE_CORES)
host->pm_qos_req_dma.cpus_affine.bits[0] = 0x0F;
else if (host->pm_qos_req_dma.type == PM_QOS_REQ_AFFINE_IRQ)
host->pm_qos_req_dma.irq = host->irq;
}
#else
static void sdhci_set_pmqos_req_type(struct sdhci_host *host)