[PATCH 06/10] remoteproc: qcom_q6v5_mss: Allow replacing regulators with power domains

Stephan Gerhold
2020-09-16T19:03:24Z

Newer platforms vote for necessary power domains through the power
domain subsystem. For historical reasons older platforms like MSM8916
or MSM8974 still control these as regulators.

Managing them as power domains is preferred since that allows us
to vote for corners instead of raw voltages.

Make it possible for MSM8916 and MSM8974 to manage these as power
domains. For compatibility with old device trees we still need to
support falling back to the regulators when necessary.

The way this is implemented here is that the deprecated regulators
are defined as "fallback_proxy_supply". Only if attaching the power
domains fails because they are not specified (-ENODATA) we request
and manage the fallback regulators instead.

Signed-off-by: Stephan Gerhold <stephan@gerhold.net>
---
drivers/remoteproc/qcom_q6v5_mss.c | 68 ++++++++++++++++++++++++------
1 file changed, 56 insertions(+), 12 deletions(-)

diff --git a/drivers/remoteproc/qcom_q6v5_mss.c b/drivers/remoteproc/qcom_q6v5_mss.c
index c401bcc263fa..98bf4230d8f4 100644
--- a/drivers/remoteproc/qcom_q6v5_mss.c
+++ b/drivers/remoteproc/qcom_q6v5_mss.c
@@ -132,6 +132,7 @@ struct qcom_mss_reg_res {
struct rproc_hexagon_res {
const char *hexagon_mba_image;
struct qcom_mss_reg_res *proxy_supply;
+ struct qcom_mss_reg_res *fallback_proxy_supply;
struct qcom_mss_reg_res *active_supply;
char **proxy_clk_names;
char **reset_clk_names;
@@ -177,9 +178,11 @@ struct q6v5 {
int proxy_pd_count;

struct reg_info active_regs[1];
- struct reg_info proxy_regs[3];
+ struct reg_info proxy_regs[1];
+ struct reg_info fallback_proxy_regs[2];
int active_reg_count;
int proxy_reg_count;
+ int fallback_proxy_reg_count;

bool dump_mba_loaded;
size_t current_dump_size;
@@ -890,11 +893,18 @@ static int q6v5_mba_load(struct q6v5 *qproc)
goto disable_active_pds;
}

+ ret = q6v5_regulator_enable(qproc, qproc->fallback_proxy_regs,
+ qproc->fallback_proxy_reg_count);
+ if (ret) {
+ dev_err(qproc->dev, "failed to enable fallback proxy supplies\n");
+ goto disable_proxy_pds;
+ }
+
ret = q6v5_regulator_enable(qproc, qproc->proxy_regs,
qproc->proxy_reg_count);
if (ret) {
dev_err(qproc->dev, "failed to enable proxy supplies\n");
- goto disable_proxy_pds;
+ goto disable_fallback_proxy_reg;
}

ret = q6v5_clk_enable(qproc->dev, qproc->proxy_clks,
@@ -997,6 +1007,9 @@ static int q6v5_mba_load(struct q6v5 *qproc)
disable_proxy_reg:
q6v5_regulator_disable(qproc, qproc->proxy_regs,
qproc->proxy_reg_count);
+disable_fallback_proxy_reg:
+ q6v5_regulator_disable(qproc, qproc->fallback_proxy_regs,
+ qproc->fallback_proxy_reg_count);
disable_proxy_pds:
q6v5_pds_disable(qproc, qproc->proxy_pds, qproc->proxy_pd_count);
disable_active_pds:
@@ -1052,6 +1065,8 @@ static void q6v5_mba_reclaim(struct q6v5 *qproc)
qproc->proxy_pd_count);
q6v5_clk_disable(qproc->dev, qproc->proxy_clks,
qproc->proxy_clk_count);
+ q6v5_regulator_disable(qproc, qproc->fallback_proxy_regs,
+ qproc->fallback_proxy_reg_count);
q6v5_regulator_disable(qproc, qproc->proxy_regs,
qproc->proxy_reg_count);
}
@@ -1413,6 +1428,8 @@ static void qcom_msa_handover(struct qcom_q6v5 *q6v5)
qproc->proxy_clk_count);
q6v5_regulator_disable(qproc, qproc->proxy_regs,
qproc->proxy_reg_count);
+ q6v5_regulator_disable(qproc, qproc->fallback_proxy_regs,
+ qproc->fallback_proxy_reg_count);
q6v5_pds_disable(qproc, qproc->proxy_pds, qproc->proxy_pd_count);
}

@@ -1707,11 +1724,22 @@ static int q6v5_probe(struct platform_device *pdev)

ret = q6v5_pds_attach(&pdev->dev, qproc->proxy_pds,
desc->proxy_pd_names);
- if (ret < 0) {
+ /* Fallback to regulators for old device trees */
+ if (ret == -ENODATA && desc->fallback_proxy_supply) {
+ ret = q6v5_regulator_init(&pdev->dev,
+ qproc->fallback_proxy_regs,
+ desc->fallback_proxy_supply);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "Failed to get fallback proxy regulators.\n");
+ goto detach_active_pds;
+ }
+ qproc->fallback_proxy_reg_count = ret;
+ } else if (ret < 0) {
dev_err(&pdev->dev, "Failed to init power domains\n");
goto detach_active_pds;
+ } else {
+ qproc->proxy_pd_count = ret;
}
- qproc->proxy_pd_count = ret;

qproc->has_alt_reset = desc->has_alt_reset;
ret = q6v5_init_reset(qproc);
@@ -1912,6 +1940,13 @@ static const struct rproc_hexagon_res msm8996_mss = {
static const struct rproc_hexagon_res msm8916_mss = {
.hexagon_mba_image = "mba.mbn",
.proxy_supply = (struct qcom_mss_reg_res[]) {
+ {
+ .supply = "pll",
+ .uA = 100000,
+ },
+ {}
+ },
+ .fallback_proxy_supply = (struct qcom_mss_reg_res[]) {
{
.supply = "mx",
.uV = 1050000,
@@ -1920,10 +1955,6 @@ static const struct rproc_hexagon_res msm8916_mss = {
.supply = "cx",
.uA = 100000,
},
- {
- .supply = "pll",
- .uA = 100000,
- },
{}
},
.proxy_clk_names = (char*[]){
@@ -1936,6 +1967,11 @@ static const struct rproc_hexagon_res msm8916_mss = {
"mem",
NULL
},
+ .proxy_pd_names = (char*[]){
+ "mx",
+ "cx",
+ NULL
+ },
.need_mem_protection = false,
.has_alt_reset = false,
.has_mba_logs = false,
@@ -1946,6 +1982,13 @@ static const struct rproc_hexagon_res msm8916_mss = {
static const struct rproc_hexagon_res msm8974_mss = {
.hexagon_mba_image = "mba.b00",
.proxy_supply = (struct qcom_mss_reg_res[]) {
+ {
+ .supply = "pll",
+ .uA = 100000,
+ },
+ {}
+ },
+ .fallback_proxy_supply = (struct qcom_mss_reg_res[]) {
{
.supply = "mx",
.uV = 1050000,
@@ -1954,10 +1997,6 @@ static const struct rproc_hexagon_res msm8974_mss = {
.supply = "cx",
.uA = 100000,
},
- {
- .supply = "pll",
- .uA = 100000,
- },
{}
},
.active_supply = (struct qcom_mss_reg_res[]) {
@@ -1978,6 +2017,11 @@ static const struct rproc_hexagon_res msm8974_mss = {
"mem",
NULL
},
+ .proxy_pd_names = (char*[]){
+ "mx",
+ "cx",
+ NULL
+ },
.need_mem_protection = false,
.has_alt_reset = false,
.has_mba_logs = false,
--
2.28.0