Skip to content

Commit

Permalink
remoteproc: qcom: pas: Vote for active/proxy power domains
Browse files Browse the repository at this point in the history
On SM8150 SoCs ADSP, CDSP and MPSS need to proxy vote on multiple
rpmh ARC resources and active vote on QMP AOSS Power domains. Add
support to vote for multiple active and proxy power domains.

Signed-off-by: Sibi Sankar <sibis@codeaurora.org>
Link: https://lore.kernel.org/r/0101016e8078a71a-9ae99638-9e15-49a5-b769-85552526ae89-000000@us-west-2.amazonses.com
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
  • Loading branch information
Sibi Sankar authored and andersson committed Dec 16, 2019
1 parent 22f517e commit 17ee2fb
Showing 1 changed file with 133 additions and 4 deletions.
137 changes: 133 additions & 4 deletions drivers/remoteproc/qcom_q6v5_pas.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
#include <linux/of_address.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/pm_domain.h>
#include <linux/pm_runtime.h>
#include <linux/qcom_scm.h>
#include <linux/regulator/consumer.h>
#include <linux/remoteproc.h>
Expand All @@ -32,6 +34,9 @@ struct adsp_data {
int pas_id;
bool has_aggre2_clk;

char **active_pd_names;
char **proxy_pd_names;

const char *ssr_name;
const char *sysmon_name;
int ssctl_id;
Expand All @@ -49,6 +54,12 @@ struct qcom_adsp {
struct regulator *cx_supply;
struct regulator *px_supply;

struct device *active_pds[1];
struct device *proxy_pds[3];

int active_pd_count;
int proxy_pd_count;

int pas_id;
int crash_reason_smem;
bool has_aggre2_clk;
Expand All @@ -67,6 +78,41 @@ struct qcom_adsp {
struct qcom_sysmon *sysmon;
};

static int adsp_pds_enable(struct qcom_adsp *adsp, struct device **pds,
size_t pd_count)
{
int ret;
int i;

for (i = 0; i < pd_count; i++) {
dev_pm_genpd_set_performance_state(pds[i], INT_MAX);
ret = pm_runtime_get_sync(pds[i]);
if (ret < 0)
goto unroll_pd_votes;
}

return 0;

unroll_pd_votes:
for (i--; i >= 0; i--) {
dev_pm_genpd_set_performance_state(pds[i], 0);
pm_runtime_put(pds[i]);
}

return ret;
};

static void adsp_pds_disable(struct qcom_adsp *adsp, struct device **pds,
size_t pd_count)
{
int i;

for (i = 0; i < pd_count; i++) {
dev_pm_genpd_set_performance_state(pds[i], 0);
pm_runtime_put(pds[i]);
}
}

static int adsp_load(struct rproc *rproc, const struct firmware *fw)
{
struct qcom_adsp *adsp = (struct qcom_adsp *)rproc->priv;
Expand All @@ -84,9 +130,17 @@ static int adsp_start(struct rproc *rproc)

qcom_q6v5_prepare(&adsp->q6v5);

ret = adsp_pds_enable(adsp, adsp->active_pds, adsp->active_pd_count);
if (ret < 0)
goto disable_irqs;

ret = adsp_pds_enable(adsp, adsp->proxy_pds, adsp->proxy_pd_count);
if (ret < 0)
goto disable_active_pds;

ret = clk_prepare_enable(adsp->xo);
if (ret)
goto disable_irqs;
goto disable_proxy_pds;

ret = clk_prepare_enable(adsp->aggre2_clk);
if (ret)
Expand Down Expand Up @@ -124,6 +178,10 @@ static int adsp_start(struct rproc *rproc)
clk_disable_unprepare(adsp->aggre2_clk);
disable_xo_clk:
clk_disable_unprepare(adsp->xo);
disable_proxy_pds:
adsp_pds_disable(adsp, adsp->proxy_pds, adsp->proxy_pd_count);
disable_active_pds:
adsp_pds_disable(adsp, adsp->active_pds, adsp->active_pd_count);
disable_irqs:
qcom_q6v5_unprepare(&adsp->q6v5);

Expand All @@ -138,6 +196,7 @@ static void qcom_pas_handover(struct qcom_q6v5 *q6v5)
regulator_disable(adsp->cx_supply);
clk_disable_unprepare(adsp->aggre2_clk);
clk_disable_unprepare(adsp->xo);
adsp_pds_disable(adsp, adsp->proxy_pds, adsp->proxy_pd_count);
}

static int adsp_stop(struct rproc *rproc)
Expand All @@ -154,6 +213,7 @@ static int adsp_stop(struct rproc *rproc)
if (ret)
dev_err(adsp->dev, "failed to shutdown: %d\n", ret);

adsp_pds_disable(adsp, adsp->active_pds, adsp->active_pd_count);
handover = qcom_q6v5_unprepare(&adsp->q6v5);
if (handover)
qcom_pas_handover(&adsp->q6v5);
Expand Down Expand Up @@ -219,6 +279,59 @@ static int adsp_init_regulator(struct qcom_adsp *adsp)
return PTR_ERR_OR_ZERO(adsp->px_supply);
}

static int adsp_pds_attach(struct device *dev, struct device **devs,
char **pd_names)
{
size_t num_pds = 0;
int ret;
int i;

if (!pd_names)
return 0;

/* Handle single power domain */
if (dev->pm_domain) {
devs[0] = dev;
pm_runtime_enable(dev);
return 1;
}

while (pd_names[num_pds])
num_pds++;

for (i = 0; i < num_pds; i++) {
devs[i] = dev_pm_domain_attach_by_name(dev, pd_names[i]);
if (IS_ERR_OR_NULL(devs[i])) {
ret = PTR_ERR(devs[i]) ? : -ENODATA;
goto unroll_attach;
}
}

return num_pds;

unroll_attach:
for (i--; i >= 0; i--)
dev_pm_domain_detach(devs[i], false);

return ret;
};

static void adsp_pds_detach(struct qcom_adsp *adsp, struct device **pds,
size_t pd_count)
{
struct device *dev = adsp->dev;
int i;

/* Handle single power domain */
if (dev->pm_domain && pd_count) {
pm_runtime_disable(dev);
return;
}

for (i = 0; i < pd_count; i++)
dev_pm_domain_detach(pds[i], false);
}

static int adsp_alloc_memory_region(struct qcom_adsp *adsp)
{
struct device_node *node;
Expand Down Expand Up @@ -294,10 +407,22 @@ static int adsp_probe(struct platform_device *pdev)
if (ret)
goto free_rproc;

ret = adsp_pds_attach(&pdev->dev, adsp->active_pds,
desc->active_pd_names);
if (ret < 0)
goto free_rproc;
adsp->active_pd_count = ret;

ret = adsp_pds_attach(&pdev->dev, adsp->proxy_pds,
desc->proxy_pd_names);
if (ret < 0)
goto detach_active_pds;
adsp->proxy_pd_count = ret;

ret = qcom_q6v5_init(&adsp->q6v5, pdev, rproc, desc->crash_reason_smem,
qcom_pas_handover);
if (ret)
goto free_rproc;
goto detach_proxy_pds;

qcom_add_glink_subdev(rproc, &adsp->glink_subdev);
qcom_add_smd_subdev(rproc, &adsp->smd_subdev);
Expand All @@ -307,15 +432,19 @@ static int adsp_probe(struct platform_device *pdev)
desc->ssctl_id);
if (IS_ERR(adsp->sysmon)) {
ret = PTR_ERR(adsp->sysmon);
goto free_rproc;
goto detach_proxy_pds;
}

ret = rproc_add(rproc);
if (ret)
goto free_rproc;
goto detach_proxy_pds;

return 0;

detach_proxy_pds:
adsp_pds_detach(adsp, adsp->proxy_pds, adsp->proxy_pd_count);
detach_active_pds:
adsp_pds_detach(adsp, adsp->active_pds, adsp->active_pd_count);
free_rproc:
rproc_free(rproc);

Expand Down

0 comments on commit 17ee2fb

Please sign in to comment.