aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStanimir Varbanov <stanimir.varbanov@linaro.org>2020-12-18 16:33:46 +0530
committerBryan O'Donoghue <bryan.odonoghue@linaro.org>2021-01-29 02:33:38 +0000
commitf78afd1423a44fdc9b9c470acd66ab6603b253e0 (patch)
treead14f4c10283602dc3a9fac7d4e8a8112d16331a
parentfcc4f909d70f46a9aee845d65f09eacf4e3cfe15 (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.h4
-rw-r--r--drivers/media/platform/qcom/venus/pm_helpers.c60
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);
}