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

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
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -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;
+60 −0
Original line number Diff line number Diff line
@@ -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);
	}