diff options
author | Stanimir Varbanov <stanimir.varbanov@linaro.org> | 2020-12-18 16:33:46 +0530 |
---|---|---|
committer | Bryan O'Donoghue <bryan.odonoghue@linaro.org> | 2021-01-29 02:33:38 +0000 |
commit | f78afd1423a44fdc9b9c470acd66ab6603b253e0 (patch) | |
tree | ad14f4c10283602dc3a9fac7d4e8a8112d16331a | |
parent | fcc4f909d70f46a9aee845d65f09eacf4e3cfe15 (diff) |
media: venus: core,pm: Add handling for resets
The Venus driver has to control two reset signals related to
gcc video_axi0 and videocc mvs0c for v6. Add it.
Signed-off-by: Stanimir Varbanov <stanimir.varbanov@linaro.org>
Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
-rw-r--r-- | drivers/media/platform/qcom/venus/core.h | 4 | ||||
-rw-r--r-- | drivers/media/platform/qcom/venus/pm_helpers.c | 60 |
2 files changed, 64 insertions, 0 deletions
diff --git a/drivers/media/platform/qcom/venus/core.h b/drivers/media/platform/qcom/venus/core.h index a252ed32cc14..771f5bb0981e 100644 --- a/drivers/media/platform/qcom/venus/core.h +++ b/drivers/media/platform/qcom/venus/core.h @@ -24,6 +24,7 @@ #define VIDC_CLKS_NUM_MAX 4 #define VIDC_VCODEC_CLKS_NUM_MAX 2 #define VIDC_PMDOMAINS_NUM_MAX 3 +#define VIDC_RESETS_NUM_MAX 2 extern int venus_fw_debug; @@ -64,6 +65,8 @@ struct venus_resources { unsigned int vcodec_pmdomains_num; const char **opp_pmdomain; unsigned int vcodec_num; + const char * const resets[VIDC_RESETS_NUM_MAX]; + unsigned int resets_num; enum hfi_version hfi_version; u32 max_load; unsigned int vmem_id; @@ -130,6 +133,7 @@ struct venus_core { struct device *pmdomains[VIDC_PMDOMAINS_NUM_MAX]; struct device_link *opp_dl_venus; struct device *opp_pmdomain; + struct reset_control *resets[VIDC_RESETS_NUM_MAX]; struct video_device *vdev_dec; struct video_device *vdev_enc; struct v4l2_device v4l2_dev; diff --git a/drivers/media/platform/qcom/venus/pm_helpers.c b/drivers/media/platform/qcom/venus/pm_helpers.c index 43c4e3d9e281..efda25cc19b3 100644 --- a/drivers/media/platform/qcom/venus/pm_helpers.c +++ b/drivers/media/platform/qcom/venus/pm_helpers.c @@ -11,6 +11,7 @@ #include <linux/pm_domain.h> #include <linux/pm_opp.h> #include <linux/pm_runtime.h> +#include <linux/reset.h> #include <linux/types.h> #include <media/v4l2-mem2mem.h> @@ -834,6 +835,52 @@ skip_pmdomains: dev_pm_opp_detach_genpd(core->opp_table); } +static int core_resets_reset(struct venus_core *core) +{ + const struct venus_resources *res = core->res; + unsigned char i; + int ret; + + if (!res->resets_num) + return 0; + + for (i = 0; i < res->resets_num; i++) { + ret = reset_control_assert(core->resets[i]); + if (ret) + goto err; + + usleep_range(150, 250); + ret = reset_control_deassert(core->resets[i]); + if (ret) + goto err; + } + +err: + return ret; +} + +static int core_resets_get(struct device *dev) +{ + struct venus_core *core = dev_get_drvdata(dev); + const struct venus_resources *res = core->res; + unsigned char i; + int ret; + + if (!res->resets_num) + return 0; + + for (i = 0; i < res->resets_num; i++) { + core->resets[i] = + devm_reset_control_get_exclusive(dev, res->resets[i]); + if (IS_ERR(core->resets[i])) { + ret = PTR_ERR(core->resets[i]); + return ret; + } + } + + return 0; +} + static int core_get_v4(struct device *dev) { struct venus_core *core = dev_get_drvdata(dev); @@ -857,6 +904,10 @@ static int core_get_v4(struct device *dev) if (ret) return ret; + ret = core_resets_get(dev); + if (ret) + return ret; + if (legacy_binding) return 0; @@ -916,6 +967,13 @@ static int core_power_v4(struct device *dev, int on) } } + ret = core_resets_reset(core); + if (ret) { + if (pmctrl) + pm_runtime_put_sync(pmctrl); + return ret; + } + ret = core_clks_enable(core); if (ret < 0 && pmctrl) pm_runtime_put_sync(pmctrl); @@ -926,6 +984,8 @@ static int core_power_v4(struct device *dev, int on) core_clks_disable(core); + ret = core_resets_reset(core); + if (pmctrl) pm_runtime_put_sync(pmctrl); } |