Commit 3bca4358 authored by Stanimir Varbanov's avatar Stanimir Varbanov Committed by Mauro Carvalho Chehab

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: default avatarStanimir Varbanov <stanimir.varbanov@linaro.org>
Signed-off-by: default avatarBryan O'Donoghue <bryan.odonoghue@linaro.org>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab+huawei@kernel.org>
parent daba0a10
......@@ -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;
......
......@@ -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>
......@@ -847,6 +848,52 @@ static void vcodec_domains_put(struct venus_core *core)
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)
{
struct device *dev = core->dev;
......@@ -870,6 +917,10 @@ static int core_get_v4(struct venus_core *core)
if (ret)
return ret;
ret = core_resets_get(core);
if (ret)
return ret;
if (legacy_binding)
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);
if (ret < 0 && 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);
ret = core_resets_reset(core);
if (pmctrl)
pm_runtime_put_sync(pmctrl);
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment