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>
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
This commit is contained in:
Stanimir Varbanov 2021-04-02 12:06:25 +02:00 committed by Mauro Carvalho Chehab
parent daba0a10c5
commit 3bca43585e
2 changed files with 64 additions and 0 deletions

View File

@ -24,6 +24,7 @@
#define VIDC_CLKS_NUM_MAX 4 #define VIDC_CLKS_NUM_MAX 4
#define VIDC_VCODEC_CLKS_NUM_MAX 2 #define VIDC_VCODEC_CLKS_NUM_MAX 2
#define VIDC_PMDOMAINS_NUM_MAX 3 #define VIDC_PMDOMAINS_NUM_MAX 3
#define VIDC_RESETS_NUM_MAX 2
extern int venus_fw_debug; extern int venus_fw_debug;
@ -64,6 +65,8 @@ struct venus_resources {
unsigned int vcodec_pmdomains_num; unsigned int vcodec_pmdomains_num;
const char **opp_pmdomain; const char **opp_pmdomain;
unsigned int vcodec_num; unsigned int vcodec_num;
const char * const resets[VIDC_RESETS_NUM_MAX];
unsigned int resets_num;
enum hfi_version hfi_version; enum hfi_version hfi_version;
u32 max_load; u32 max_load;
unsigned int vmem_id; unsigned int vmem_id;
@ -130,6 +133,7 @@ struct venus_core {
struct device *pmdomains[VIDC_PMDOMAINS_NUM_MAX]; struct device *pmdomains[VIDC_PMDOMAINS_NUM_MAX];
struct device_link *opp_dl_venus; struct device_link *opp_dl_venus;
struct device *opp_pmdomain; struct device *opp_pmdomain;
struct reset_control *resets[VIDC_RESETS_NUM_MAX];
struct video_device *vdev_dec; struct video_device *vdev_dec;
struct video_device *vdev_enc; struct video_device *vdev_enc;
struct v4l2_device v4l2_dev; struct v4l2_device v4l2_dev;

View File

@ -11,6 +11,7 @@
#include <linux/pm_domain.h> #include <linux/pm_domain.h>
#include <linux/pm_opp.h> #include <linux/pm_opp.h>
#include <linux/pm_runtime.h> #include <linux/pm_runtime.h>
#include <linux/reset.h>
#include <linux/types.h> #include <linux/types.h>
#include <media/v4l2-mem2mem.h> #include <media/v4l2-mem2mem.h>
@ -847,6 +848,52 @@ skip_pmdomains:
dev_pm_opp_detach_genpd(core->opp_table); 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 venus_core *core)
{
struct device *dev = core->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 venus_core *core) static int core_get_v4(struct venus_core *core)
{ {
struct device *dev = core->dev; struct device *dev = core->dev;
@ -870,6 +917,10 @@ static int core_get_v4(struct venus_core *core)
if (ret) if (ret)
return ret; return ret;
ret = core_resets_get(core);
if (ret)
return ret;
if (legacy_binding) if (legacy_binding)
return 0; return 0;
@ -929,6 +980,13 @@ static int core_power_v4(struct venus_core *core, int on)
} }
} }
ret = core_resets_reset(core);
if (ret) {
if (pmctrl)
pm_runtime_put_sync(pmctrl);
return ret;
}
ret = core_clks_enable(core); ret = core_clks_enable(core);
if (ret < 0 && pmctrl) if (ret < 0 && pmctrl)
pm_runtime_put_sync(pmctrl); pm_runtime_put_sync(pmctrl);
@ -939,6 +997,8 @@ static int core_power_v4(struct venus_core *core, int on)
core_clks_disable(core); core_clks_disable(core);
ret = core_resets_reset(core);
if (pmctrl) if (pmctrl)
pm_runtime_put_sync(pmctrl); pm_runtime_put_sync(pmctrl);
} }