summaryrefslogtreecommitdiff
path: root/drivers/media/platform/qcom/venus/pm_helpers.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/platform/qcom/venus/pm_helpers.c')
-rw-r--r--drivers/media/platform/qcom/venus/pm_helpers.c84
1 files changed, 34 insertions, 50 deletions
diff --git a/drivers/media/platform/qcom/venus/pm_helpers.c b/drivers/media/platform/qcom/venus/pm_helpers.c
index 502822059498..409aa9bd0b5d 100644
--- a/drivers/media/platform/qcom/venus/pm_helpers.c
+++ b/drivers/media/platform/qcom/venus/pm_helpers.c
@@ -412,10 +412,17 @@ static int vcodec_control_v4(struct venus_core *core, u32 coreid, bool enable)
u32 val;
int ret;
- if (IS_V6(core)) {
- ctrl = core->wrapper_base + WRAPPER_CORE_POWER_CONTROL_V6;
- stat = core->wrapper_base + WRAPPER_CORE_POWER_STATUS_V6;
- } else if (coreid == VIDC_CORE_ID_1) {
+ ret = dev_pm_genpd_set_hwmode(core->pmdomains->pd_devs[coreid], !enable);
+ if (ret == -EOPNOTSUPP) {
+ core->hwmode_dev = false;
+ goto legacy;
+ }
+
+ core->hwmode_dev = true;
+ return ret;
+
+legacy:
+ if (coreid == VIDC_CORE_ID_1) {
ctrl = core->wrapper_base + WRAPPER_VCODEC0_MMCC_POWER_CONTROL;
stat = core->wrapper_base + WRAPPER_VCODEC0_MMCC_POWER_STATUS;
} else {
@@ -451,9 +458,11 @@ static int poweroff_coreid(struct venus_core *core, unsigned int coreid_mask)
vcodec_clks_disable(core, core->vcodec0_clks);
- ret = vcodec_control_v4(core, VIDC_CORE_ID_1, false);
- if (ret)
- return ret;
+ if (!core->hwmode_dev) {
+ ret = vcodec_control_v4(core, VIDC_CORE_ID_1, false);
+ if (ret)
+ return ret;
+ }
ret = pm_runtime_put_sync(core->pmdomains->pd_devs[1]);
if (ret < 0)
@@ -467,9 +476,11 @@ static int poweroff_coreid(struct venus_core *core, unsigned int coreid_mask)
vcodec_clks_disable(core, core->vcodec1_clks);
- ret = vcodec_control_v4(core, VIDC_CORE_ID_2, false);
- if (ret)
- return ret;
+ if (!core->hwmode_dev) {
+ ret = vcodec_control_v4(core, VIDC_CORE_ID_2, false);
+ if (ret)
+ return ret;
+ }
ret = pm_runtime_put_sync(core->pmdomains->pd_devs[2]);
if (ret < 0)
@@ -804,7 +815,7 @@ static int vdec_power_v4(struct device *dev, int on)
else
vcodec_clks_disable(core, core->vcodec0_clks);
- vcodec_control_v4(core, VIDC_CORE_ID_1, false);
+ ret = vcodec_control_v4(core, VIDC_CORE_ID_1, false);
return ret;
}
@@ -849,7 +860,7 @@ static int venc_power_v4(struct device *dev, int on)
else
vcodec_clks_disable(core, core->vcodec1_clks);
- vcodec_control_v4(core, VIDC_CORE_ID_2, false);
+ ret = vcodec_control_v4(core, VIDC_CORE_ID_2, false);
return ret;
}
@@ -857,7 +868,6 @@ static int venc_power_v4(struct device *dev, int on)
static int vcodec_domains_get(struct venus_core *core)
{
int ret;
- struct device **opp_virt_dev;
struct device *dev = core->dev;
const struct venus_resources *res = core->res;
struct dev_pm_domain_attach_data vcodec_data = {
@@ -865,49 +875,29 @@ static int vcodec_domains_get(struct venus_core *core)
.num_pd_names = res->vcodec_pmdomains_num,
.pd_flags = PD_FLAG_NO_DEV_LINK,
};
+ struct dev_pm_domain_attach_data opp_pd_data = {
+ .pd_names = res->opp_pmdomain,
+ .num_pd_names = 1,
+ .pd_flags = PD_FLAG_DEV_LINK_ON | PD_FLAG_REQUIRED_OPP,
+ };
if (!res->vcodec_pmdomains_num)
goto skip_pmdomains;
- ret = dev_pm_domain_attach_list(dev, &vcodec_data, &core->pmdomains);
+ ret = devm_pm_domain_attach_list(dev, &vcodec_data, &core->pmdomains);
if (ret < 0)
return ret;
skip_pmdomains:
- if (!core->res->opp_pmdomain)
+ if (!res->opp_pmdomain)
return 0;
/* Attach the power domain for setting performance state */
- ret = devm_pm_opp_attach_genpd(dev, res->opp_pmdomain, &opp_virt_dev);
- if (ret)
- goto opp_attach_err;
-
- core->opp_pmdomain = *opp_virt_dev;
- core->opp_dl_venus = device_link_add(dev, core->opp_pmdomain,
- DL_FLAG_RPM_ACTIVE |
- DL_FLAG_PM_RUNTIME |
- DL_FLAG_STATELESS);
- if (!core->opp_dl_venus) {
- ret = -ENODEV;
- goto opp_attach_err;
- }
+ ret = devm_pm_domain_attach_list(dev, &opp_pd_data, &core->opp_pmdomain);
+ if (ret < 0)
+ return ret;
return 0;
-
-opp_attach_err:
- dev_pm_domain_detach_list(core->pmdomains);
- return ret;
-}
-
-static void vcodec_domains_put(struct venus_core *core)
-{
- dev_pm_domain_detach_list(core->pmdomains);
-
- if (!core->has_opp_table)
- return;
-
- if (core->opp_dl_venus)
- device_link_del(core->opp_dl_venus);
}
static int core_resets_reset(struct venus_core *core)
@@ -996,9 +986,7 @@ static int core_get_v4(struct venus_core *core)
if (core->res->opp_pmdomain) {
ret = devm_pm_opp_of_add_table(dev);
- if (!ret) {
- core->has_opp_table = true;
- } else if (ret != -ENODEV) {
+ if (ret && ret != -ENODEV) {
dev_err(dev, "invalid OPP table in device tree\n");
return ret;
}
@@ -1009,10 +997,6 @@ static int core_get_v4(struct venus_core *core)
static void core_put_v4(struct venus_core *core)
{
- if (legacy_binding)
- return;
-
- vcodec_domains_put(core);
}
static int core_power_v4(struct venus_core *core, int on)