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:
parent
daba0a10c5
commit
3bca43585e
@ -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 @@ 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 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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user