summaryrefslogtreecommitdiff
path: root/drivers/pmdomain/qcom
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pmdomain/qcom')
-rw-r--r--drivers/pmdomain/qcom/Kconfig41
-rw-r--r--drivers/pmdomain/qcom/cpr.c7
-rw-r--r--drivers/pmdomain/qcom/rpmhpd.c83
-rw-r--r--drivers/pmdomain/qcom/rpmpd.c98
4 files changed, 208 insertions, 21 deletions
diff --git a/drivers/pmdomain/qcom/Kconfig b/drivers/pmdomain/qcom/Kconfig
new file mode 100644
index 000000000000..3d3948eabef0
--- /dev/null
+++ b/drivers/pmdomain/qcom/Kconfig
@@ -0,0 +1,41 @@
+# SPDX-License-Identifier: GPL-2.0-only
+menu "Qualcomm PM Domains"
+
+config QCOM_CPR
+ tristate "QCOM Core Power Reduction (CPR) support"
+ depends on ARCH_QCOM && HAS_IOMEM
+ select PM_OPP
+ select REGMAP
+ help
+ Say Y here to enable support for the CPR hardware found on Qualcomm
+ SoCs like QCS404.
+
+ This driver populates CPU OPPs tables and makes adjustments to the
+ tables based on feedback from the CPR hardware. If you want to do
+ CPUfrequency scaling say Y here.
+
+ To compile this driver as a module, choose M here: the module will
+ be called qcom-cpr
+
+config QCOM_RPMHPD
+ tristate "Qualcomm RPMh Power domain driver"
+ depends on QCOM_RPMH && QCOM_COMMAND_DB
+ help
+ QCOM RPMh Power domain driver to support power-domains with
+ performance states. The driver communicates a performance state
+ value to RPMh which then translates it into corresponding voltage
+ for the voltage rail.
+
+config QCOM_RPMPD
+ tristate "Qualcomm RPM Power domain driver"
+ depends on PM && OF
+ depends on QCOM_SMD_RPM
+ select PM_GENERIC_DOMAINS
+ select PM_GENERIC_DOMAINS_OF
+ help
+ QCOM RPM Power domain driver to support power-domains with
+ performance states. The driver communicates a performance state
+ value to RPM which then translates it into corresponding voltage
+ for the voltage rail.
+
+endmenu
diff --git a/drivers/pmdomain/qcom/cpr.c b/drivers/pmdomain/qcom/cpr.c
index 94a3f0977212..e9dd42bded6f 100644
--- a/drivers/pmdomain/qcom/cpr.c
+++ b/drivers/pmdomain/qcom/cpr.c
@@ -1424,12 +1424,6 @@ static const struct cpr_acc_desc qcs404_cpr_acc_desc = {
.acc_desc = &qcs404_acc_desc,
};
-static unsigned int cpr_get_performance_state(struct generic_pm_domain *genpd,
- struct dev_pm_opp *opp)
-{
- return dev_pm_opp_get_level(opp);
-}
-
static int cpr_power_off(struct generic_pm_domain *domain)
{
struct cpr_drv *drv = container_of(domain, struct cpr_drv, pd);
@@ -1698,7 +1692,6 @@ static int cpr_probe(struct platform_device *pdev)
drv->pd.power_off = cpr_power_off;
drv->pd.power_on = cpr_power_on;
drv->pd.set_performance_state = cpr_set_performance_state;
- drv->pd.opp_to_performance_state = cpr_get_performance_state;
drv->pd.attach_dev = cpr_pd_attach_dev;
ret = pm_genpd_init(&drv->pd, NULL, true);
diff --git a/drivers/pmdomain/qcom/rpmhpd.c b/drivers/pmdomain/qcom/rpmhpd.c
index a87e336d5e33..f2e64324deb8 100644
--- a/drivers/pmdomain/qcom/rpmhpd.c
+++ b/drivers/pmdomain/qcom/rpmhpd.c
@@ -197,11 +197,21 @@ static struct rpmhpd nsp1 = {
.res_name = "nsp1.lvl",
};
+static struct rpmhpd nsp2 = {
+ .pd = { .name = "nsp2", },
+ .res_name = "nsp2.lvl",
+};
+
static struct rpmhpd qphy = {
.pd = { .name = "qphy", },
.res_name = "qphy.lvl",
};
+static struct rpmhpd gmxc = {
+ .pd = { .name = "gmxc", },
+ .res_name = "gmxc.lvl",
+};
+
/* SA8540P RPMH powerdomains */
static struct rpmhpd *sa8540p_rpmhpds[] = {
[SC8280XP_CX] = &cx,
@@ -337,6 +347,23 @@ static const struct rpmhpd_desc sm6350_desc = {
.num_pds = ARRAY_SIZE(sm6350_rpmhpds),
};
+/* SM7150 RPMH powerdomains */
+static struct rpmhpd *sm7150_rpmhpds[] = {
+ [RPMHPD_CX] = &cx_w_mx_parent,
+ [RPMHPD_CX_AO] = &cx_ao_w_mx_parent,
+ [RPMHPD_GFX] = &gfx,
+ [RPMHPD_LCX] = &lcx,
+ [RPMHPD_LMX] = &lmx,
+ [RPMHPD_MX] = &mx,
+ [RPMHPD_MX_AO] = &mx_ao,
+ [RPMHPD_MSS] = &mss,
+};
+
+static const struct rpmhpd_desc sm7150_desc = {
+ .rpmhpds = sm7150_rpmhpds,
+ .num_pds = ARRAY_SIZE(sm7150_rpmhpds),
+};
+
/* SM8150 RPMH powerdomains */
static struct rpmhpd *sm8150_rpmhpds[] = {
[SM8150_CX] = &cx_w_mx_parent,
@@ -458,6 +485,30 @@ static const struct rpmhpd_desc sm8550_desc = {
.num_pds = ARRAY_SIZE(sm8550_rpmhpds),
};
+/* SM8650 RPMH powerdomains */
+static struct rpmhpd *sm8650_rpmhpds[] = {
+ [RPMHPD_CX] = &cx,
+ [RPMHPD_CX_AO] = &cx_ao,
+ [RPMHPD_EBI] = &ebi,
+ [RPMHPD_GFX] = &gfx,
+ [RPMHPD_LCX] = &lcx,
+ [RPMHPD_LMX] = &lmx,
+ [RPMHPD_MMCX] = &mmcx_w_cx_parent,
+ [RPMHPD_MMCX_AO] = &mmcx_ao_w_cx_parent,
+ [RPMHPD_MSS] = &mss,
+ [RPMHPD_MX] = &mx,
+ [RPMHPD_MX_AO] = &mx_ao,
+ [RPMHPD_MXC] = &mxc,
+ [RPMHPD_MXC_AO] = &mxc_ao,
+ [RPMHPD_NSP] = &nsp,
+ [RPMHPD_NSP2] = &nsp2,
+};
+
+static const struct rpmhpd_desc sm8650_desc = {
+ .rpmhpds = sm8650_rpmhpds,
+ .num_pds = ARRAY_SIZE(sm8650_rpmhpds),
+};
+
/* QDU1000/QRU1000 RPMH powerdomains */
static struct rpmhpd *qdu1000_rpmhpds[] = {
[QDU1000_CX] = &cx,
@@ -547,6 +598,28 @@ static const struct rpmhpd_desc sc8280xp_desc = {
.num_pds = ARRAY_SIZE(sc8280xp_rpmhpds),
};
+/* SC8380xp RPMH powerdomains */
+static struct rpmhpd *sc8380xp_rpmhpds[] = {
+ [RPMHPD_CX] = &cx,
+ [RPMHPD_CX_AO] = &cx_ao,
+ [RPMHPD_EBI] = &ebi,
+ [RPMHPD_GFX] = &gfx,
+ [RPMHPD_LCX] = &lcx,
+ [RPMHPD_LMX] = &lmx,
+ [RPMHPD_MMCX] = &mmcx,
+ [RPMHPD_MMCX_AO] = &mmcx_ao,
+ [RPMHPD_MX] = &mx,
+ [RPMHPD_MX_AO] = &mx_ao,
+ [RPMHPD_NSP] = &nsp,
+ [RPMHPD_MXC] = &mxc,
+ [RPMHPD_GMXC] = &gmxc,
+};
+
+static const struct rpmhpd_desc sc8380xp_desc = {
+ .rpmhpds = sc8380xp_rpmhpds,
+ .num_pds = ARRAY_SIZE(sc8380xp_rpmhpds),
+};
+
static const struct of_device_id rpmhpd_match_table[] = {
{ .compatible = "qcom,qdu1000-rpmhpd", .data = &qdu1000_desc },
{ .compatible = "qcom,sa8155p-rpmhpd", .data = &sa8155p_desc },
@@ -556,17 +629,20 @@ static const struct of_device_id rpmhpd_match_table[] = {
{ .compatible = "qcom,sc7280-rpmhpd", .data = &sc7280_desc },
{ .compatible = "qcom,sc8180x-rpmhpd", .data = &sc8180x_desc },
{ .compatible = "qcom,sc8280xp-rpmhpd", .data = &sc8280xp_desc },
+ { .compatible = "qcom,sc8380xp-rpmhpd", .data = &sc8380xp_desc },
{ .compatible = "qcom,sdm670-rpmhpd", .data = &sdm670_desc },
{ .compatible = "qcom,sdm845-rpmhpd", .data = &sdm845_desc },
{ .compatible = "qcom,sdx55-rpmhpd", .data = &sdx55_desc},
{ .compatible = "qcom,sdx65-rpmhpd", .data = &sdx65_desc},
{ .compatible = "qcom,sdx75-rpmhpd", .data = &sdx75_desc},
{ .compatible = "qcom,sm6350-rpmhpd", .data = &sm6350_desc },
+ { .compatible = "qcom,sm7150-rpmhpd", .data = &sm7150_desc },
{ .compatible = "qcom,sm8150-rpmhpd", .data = &sm8150_desc },
{ .compatible = "qcom,sm8250-rpmhpd", .data = &sm8250_desc },
{ .compatible = "qcom,sm8350-rpmhpd", .data = &sm8350_desc },
{ .compatible = "qcom,sm8450-rpmhpd", .data = &sm8450_desc },
{ .compatible = "qcom,sm8550-rpmhpd", .data = &sm8550_desc },
+ { .compatible = "qcom,sm8650-rpmhpd", .data = &sm8650_desc },
{ }
};
MODULE_DEVICE_TABLE(of, rpmhpd_match_table);
@@ -725,12 +801,6 @@ out:
return ret;
}
-static unsigned int rpmhpd_get_performance_state(struct generic_pm_domain *genpd,
- struct dev_pm_opp *opp)
-{
- return dev_pm_opp_get_level(opp);
-}
-
static int rpmhpd_update_level_mapping(struct rpmhpd *rpmhpd)
{
int i;
@@ -820,7 +890,6 @@ static int rpmhpd_probe(struct platform_device *pdev)
rpmhpds[i]->pd.power_off = rpmhpd_power_off;
rpmhpds[i]->pd.power_on = rpmhpd_power_on;
rpmhpds[i]->pd.set_performance_state = rpmhpd_set_performance_state;
- rpmhpds[i]->pd.opp_to_performance_state = rpmhpd_get_performance_state;
pm_genpd_init(&rpmhpds[i]->pd, NULL, true);
data->domains[i] = &rpmhpds[i]->pd;
diff --git a/drivers/pmdomain/qcom/rpmpd.c b/drivers/pmdomain/qcom/rpmpd.c
index 3135dd1dafe0..07590a3ef19c 100644
--- a/drivers/pmdomain/qcom/rpmpd.c
+++ b/drivers/pmdomain/qcom/rpmpd.c
@@ -105,6 +105,24 @@ static struct rpmpd cx_s1a_corner_ao = {
.key = KEY_CORNER,
};
+static struct rpmpd cx_s1a_lvl_ao;
+static struct rpmpd cx_s1a_lvl = {
+ .pd = { .name = "cx", },
+ .peer = &cx_s1a_lvl_ao,
+ .res_type = RPMPD_SMPA,
+ .res_id = 1,
+ .key = KEY_LEVEL,
+};
+
+static struct rpmpd cx_s1a_lvl_ao = {
+ .pd = { .name = "cx_ao", },
+ .peer = &cx_s1a_lvl,
+ .active_only = true,
+ .res_type = RPMPD_SMPA,
+ .res_id = 1,
+ .key = KEY_LEVEL,
+};
+
static struct rpmpd cx_s2a_corner_ao;
static struct rpmpd cx_s2a_corner = {
.pd = { .name = "cx", },
@@ -180,6 +198,13 @@ static struct rpmpd cx_s1a_vfc = {
.key = KEY_FLOOR_CORNER,
};
+static struct rpmpd cx_s1a_vfl = {
+ .pd = { .name = "cx_vfl", },
+ .res_type = RPMPD_SMPA,
+ .res_id = 1,
+ .key = KEY_FLOOR_LEVEL,
+};
+
static struct rpmpd cx_s2a_vfc = {
.pd = { .name = "cx_vfc", },
.res_type = RPMPD_SMPA,
@@ -239,6 +264,24 @@ static struct rpmpd gx_rwgx0_lvl_ao = {
};
/* MX */
+static struct rpmpd mx_l2a_lvl_ao;
+static struct rpmpd mx_l2a_lvl = {
+ .pd = { .name = "mx", },
+ .peer = &mx_l2a_lvl_ao,
+ .res_type = RPMPD_LDOA,
+ .res_id = 2,
+ .key = KEY_LEVEL,
+};
+
+static struct rpmpd mx_l2a_lvl_ao = {
+ .pd = { .name = "mx_ao", },
+ .peer = &mx_l2a_lvl,
+ .active_only = true,
+ .res_type = RPMPD_LDOA,
+ .res_id = 2,
+ .key = KEY_LEVEL,
+};
+
static struct rpmpd mx_l3a_corner_ao;
static struct rpmpd mx_l3a_corner = {
.pd = { .name = "mx", },
@@ -257,6 +300,24 @@ static struct rpmpd mx_l3a_corner_ao = {
.key = KEY_CORNER,
};
+static struct rpmpd mx_l3a_lvl_ao;
+static struct rpmpd mx_l3a_lvl = {
+ .pd = { .name = "mx", },
+ .peer = &mx_l3a_lvl_ao,
+ .res_type = RPMPD_LDOA,
+ .res_id = 3,
+ .key = KEY_LEVEL,
+};
+
+static struct rpmpd mx_l3a_lvl_ao = {
+ .pd = { .name = "mx_ao", },
+ .peer = &mx_l3a_lvl,
+ .active_only = true,
+ .res_type = RPMPD_LDOA,
+ .res_id = 3,
+ .key = KEY_LEVEL,
+};
+
static struct rpmpd mx_l12a_lvl_ao;
static struct rpmpd mx_l12a_lvl = {
.pd = { .name = "mx", },
@@ -572,6 +633,20 @@ static const struct rpmpd_desc msm8916_desc = {
.max_state = MAX_CORNER_RPMPD_STATE,
};
+static struct rpmpd *msm8917_rpmpds[] = {
+ [MSM8917_VDDCX] = &cx_s2a_lvl,
+ [MSM8917_VDDCX_AO] = &cx_s2a_lvl_ao,
+ [MSM8917_VDDCX_VFL] = &cx_s2a_vfl,
+ [MSM8917_VDDMX] = &mx_l3a_lvl,
+ [MSM8917_VDDMX_AO] = &mx_l3a_lvl_ao,
+};
+
+static const struct rpmpd_desc msm8917_desc = {
+ .rpmpds = msm8917_rpmpds,
+ .num_pds = ARRAY_SIZE(msm8917_rpmpds),
+ .max_state = RPM_SMD_LEVEL_TURBO,
+};
+
static struct rpmpd *msm8953_rpmpds[] = {
[MSM8953_VDDMD] = &md_s1a_lvl,
[MSM8953_VDDMD_AO] = &md_s1a_lvl_ao,
@@ -672,6 +747,20 @@ static const struct rpmpd_desc qcs404_desc = {
.max_state = RPM_SMD_LEVEL_BINNING,
};
+static struct rpmpd *qm215_rpmpds[] = {
+ [QM215_VDDCX] = &cx_s1a_lvl,
+ [QM215_VDDCX_AO] = &cx_s1a_lvl_ao,
+ [QM215_VDDCX_VFL] = &cx_s1a_vfl,
+ [QM215_VDDMX] = &mx_l2a_lvl,
+ [QM215_VDDMX_AO] = &mx_l2a_lvl_ao,
+};
+
+static const struct rpmpd_desc qm215_desc = {
+ .rpmpds = qm215_rpmpds,
+ .num_pds = ARRAY_SIZE(qm215_rpmpds),
+ .max_state = RPM_SMD_LEVEL_TURBO,
+};
+
static struct rpmpd *sdm660_rpmpds[] = {
[SDM660_VDDCX] = &cx_rwcx0_lvl,
[SDM660_VDDCX_AO] = &cx_rwcx0_lvl_ao,
@@ -764,6 +853,7 @@ static const struct of_device_id rpmpd_match_table[] = {
{ .compatible = "qcom,msm8226-rpmpd", .data = &msm8226_desc },
{ .compatible = "qcom,msm8909-rpmpd", .data = &msm8916_desc },
{ .compatible = "qcom,msm8916-rpmpd", .data = &msm8916_desc },
+ { .compatible = "qcom,msm8917-rpmpd", .data = &msm8917_desc },
{ .compatible = "qcom,msm8939-rpmpd", .data = &msm8939_desc },
{ .compatible = "qcom,msm8953-rpmpd", .data = &msm8953_desc },
{ .compatible = "qcom,msm8976-rpmpd", .data = &msm8976_desc },
@@ -772,6 +862,7 @@ static const struct of_device_id rpmpd_match_table[] = {
{ .compatible = "qcom,msm8998-rpmpd", .data = &msm8998_desc },
{ .compatible = "qcom,qcm2290-rpmpd", .data = &qcm2290_desc },
{ .compatible = "qcom,qcs404-rpmpd", .data = &qcs404_desc },
+ { .compatible = "qcom,qm215-rpmpd", .data = &qm215_desc },
{ .compatible = "qcom,sdm660-rpmpd", .data = &sdm660_desc },
{ .compatible = "qcom,sm6115-rpmpd", .data = &sm6115_desc },
{ .compatible = "qcom,sm6125-rpmpd", .data = &sm6125_desc },
@@ -908,12 +999,6 @@ out:
return ret;
}
-static unsigned int rpmpd_get_performance(struct generic_pm_domain *genpd,
- struct dev_pm_opp *opp)
-{
- return dev_pm_opp_get_level(opp);
-}
-
static int rpmpd_probe(struct platform_device *pdev)
{
int i;
@@ -959,7 +1044,6 @@ static int rpmpd_probe(struct platform_device *pdev)
rpmpds[i]->pd.power_off = rpmpd_power_off;
rpmpds[i]->pd.power_on = rpmpd_power_on;
rpmpds[i]->pd.set_performance_state = rpmpd_set_performance;
- rpmpds[i]->pd.opp_to_performance_state = rpmpd_get_performance;
pm_genpd_init(&rpmpds[i]->pd, NULL, true);
data->domains[i] = &rpmpds[i]->pd;