Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1da860bf authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: vidc: Reset AXI CBCR register during hardware hung"

parents 4fa4a080 40d18910
Loading
Loading
Loading
Loading
+52 −5
Original line number Diff line number Diff line
@@ -46,6 +46,8 @@
#define REG_ADDR_OFFSET_BITMASK	0x000FFFFF
#define QDSS_IOVA_START 0x80001000

#define VERSION_HANA (0x5 << 28 | 0x10 << 16)

static struct hal_device_data hal_ctxt;

#define TZBSP_MEM_PROTECT_VIDEO_VAR 0x8
@@ -3976,6 +3978,42 @@ static inline int __prepare_ahb2axi_bridge(struct venus_hfi_device *device)
	return 0;
}

static inline int __unprepare_ahb2axi_bridge(struct venus_hfi_device *device,
		u32 version)
{
	int rc;

	if (!device) {
		dprintk(VIDC_ERR, "NULL device\n");
		return -EINVAL;
	}

	/* reset axi0 and axi1 as needed only for specific video hardware */
	version &= ~GENMASK(15, 0);
	if (version != VERSION_HANA)
		return -EINVAL;

	dprintk(VIDC_ERR,
			"reset axi cbcr to recover\n");

	rc = __handle_reset_clk(device->res, ASSERT);
	if (rc) {
		dprintk(VIDC_ERR, "failed to assert reset clocks\n");
		return rc;
	}

	/* wait for deassert */
	usleep_range(150, 250);

	rc = __handle_reset_clk(device->res, DEASSERT);
	if (rc) {
		dprintk(VIDC_ERR, "failed to deassert reset clocks\n");
		return rc;
	}

	return 0;
}

static inline int __prepare_enable_clks(struct venus_hfi_device *device)
{
	struct clock_info *cl = NULL, *cl_fail = NULL;
@@ -4715,8 +4753,10 @@ static int __venus_power_on(struct venus_hfi_device *device)
	return rc;
}

static void __venus_power_off(struct venus_hfi_device *device)
static void __venus_power_off(struct venus_hfi_device *device, bool axi_reset)
{
	u32 version;

	if (!device->power_enabled)
		return;

@@ -4724,7 +4764,14 @@ static void __venus_power_off(struct venus_hfi_device *device)
		disable_irq_nosync(device->hal_data->irq);
	device->intr_status = 0;

	if (axi_reset)
		version = __read_register(device, VIDC_WRAPPER_HW_VERSION);

	__disable_unprepare_clks(device);

	if (axi_reset)
		__unprepare_ahb2axi_bridge(device, version);

	if (__disable_regulators(device))
		dprintk(VIDC_WARN, "Failed to disable regulators\n");

@@ -4759,7 +4806,7 @@ static inline int __suspend(struct venus_hfi_device *device)

	__disable_subcaches(device);

	__venus_power_off(device);
	__venus_power_off(device, false);
	dprintk(VIDC_PROF, "Venus power off\n");
	return rc;

@@ -4834,7 +4881,7 @@ static inline int __resume(struct venus_hfi_device *device)
err_reset_core:
	__tzbsp_set_video_state(TZBSP_VIDEO_STATE_SUSPEND);
err_set_video_state:
	__venus_power_off(device);
	__venus_power_off(device, false);
err_venus_power_on:
	dprintk(VIDC_ERR, "Failed to resume from power collapse\n");
	return rc;
@@ -4893,7 +4940,7 @@ static int __load_fw(struct venus_hfi_device *device)
		subsystem_put(device->resources.fw.cookie);
	device->resources.fw.cookie = NULL;
fail_load_fw:
	__venus_power_off(device);
	__venus_power_off(device, true);
fail_venus_power_on:
fail_init_pkt:
	__deinit_resources(device);
@@ -4914,7 +4961,7 @@ static void __unload_fw(struct venus_hfi_device *device)
	__vote_buses(device, NULL, 0);
	subsystem_put(device->resources.fw.cookie);
	__interface_queues_release(device);
	__venus_power_off(device);
	__venus_power_off(device, true);
	device->resources.fw.cookie = NULL;
	__deinit_resources(device);