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

Commit 5e408d2b authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: vidc: Halt axi bus before clock disable"

parents 3aaff568 08db96a4
Loading
Loading
Loading
Loading
+42 −5
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@
#include <mach/subsystem_restart.h>
#include <mach/msm_smem.h>
#include <asm/memory.h>
#include <linux/iopoll.h>
#include "hfi_packetization.h"
#include "venus_hfi.h"
#include "vidc_hfi_io.h"
@@ -65,6 +66,9 @@ struct tzbsp_resp {

#define TZBSP_VIDEO_SET_STATE 0xa

/* Poll interval in uS */
#define POLL_INTERVAL_US 50

enum tzbsp_video_state {
	TZBSP_VIDEO_STATE_SUSPEND = 0,
	TZBSP_VIDEO_STATE_RESUME
@@ -77,6 +81,8 @@ struct tzbsp_video_set_state_req {

static int venus_hfi_power_enable(void *dev);

static inline int venus_hfi_clk_gating_off(struct venus_hfi_device *device);

static void venus_hfi_dump_packet(u8 *packet)
{
	u32 c = 0, packet_size = *(u32 *)packet;
@@ -917,6 +923,34 @@ static inline void venus_hfi_clk_disable(struct venus_hfi_device *device)

static DECLARE_COMPLETION(pc_prep_done);

static int venus_hfi_halt_axi(struct venus_hfi_device *device)
{
	u32 reg;
	int rc = 0;
	if (!device) {
		dprintk(VIDC_ERR, "Invalid input: %p\n", device);
		return -EINVAL;
	}
	if (venus_hfi_clk_gating_off(device)) {
		dprintk(VIDC_ERR, "Failed to turn off clk gating\n");
		return -EIO;
	}
	/* Halt AXI and AXI OCMEM VBIF Access */
	reg = venus_hfi_read_register(device, VENUS_VBIF_AXI_HALT_CTRL0);
	reg |= VENUS_VBIF_AXI_HALT_CTRL0_HALT_REQ;
	venus_hfi_write_register(device, VENUS_VBIF_AXI_HALT_CTRL0, reg, 0);

	/* Request for AXI bus port halt */
	rc = readl_poll_timeout((u32)device->hal_data->register_base_addr
			+ VENUS_VBIF_AXI_HALT_CTRL1,
			reg, reg & VENUS_VBIF_AXI_HALT_CTRL1_HALT_ACK,
			POLL_INTERVAL_US,
			VENUS_VBIF_AXI_HALT_ACK_TIMEOUT_US);
	if (rc)
		dprintk(VIDC_WARN, "AXI bus port halt timeout\n");
	return rc;
}

static inline int venus_hfi_power_off(struct venus_hfi_device *device)
{
	int rc = 0;
@@ -3443,15 +3477,18 @@ static void venus_hfi_unload_fw(void *dev)
	if (device->resources.fw.cookie) {
		flush_workqueue(device->vidc_workq);
		flush_workqueue(device->venus_pm_workq);
		venus_hfi_disable_clks(device);
		mutex_lock(&device->clk_pwr_lock);
		subsystem_put(device->resources.fw.cookie);
		venus_hfi_disable_regulators(device);
		mutex_unlock(&device->clk_pwr_lock);
		venus_hfi_interface_queues_release(dev);
		/* IOMMU operations need to be done before AXI halt.*/
		venus_hfi_iommu_detach(device);

		/* Halt the AXI to make sure there are no pending transactions.
		 * Clocks should be unprepared after making sure axi is halted.
		 */
		if (venus_hfi_halt_axi(device))
			dprintk(VIDC_WARN, "Failed to halt AXI\n");
		venus_hfi_disable_clks(device);
		mutex_lock(&device->clk_pwr_lock);
		venus_hfi_disable_regulators(device);
		device->power_enabled = 0;
		mutex_unlock(&device->clk_pwr_lock);
		device->resources.fw.cookie = NULL;
+6 −0
Original line number Diff line number Diff line
@@ -131,6 +131,12 @@
#define VIDC_VBIF_AT_OLD_HIGH           (VIDC_VBIF_BASE_OFFS + 0xC08)
#define VIDC_VBIF_AT_NEW_BASE           (VIDC_VBIF_BASE_OFFS + 0xC10)
#define VIDC_VBIF_AT_NEW_HIGH           (VIDC_VBIF_BASE_OFFS + 0xC18)
#define VENUS_VBIF_AXI_HALT_CTRL0   (VIDC_VBIF_BASE_OFFS + 0x208)
#define VENUS_VBIF_AXI_HALT_CTRL1   (VIDC_VBIF_BASE_OFFS + 0x20C)

#define VENUS_VBIF_AXI_HALT_CTRL0_HALT_REQ		BIT(0)
#define VENUS_VBIF_AXI_HALT_CTRL1_HALT_ACK		BIT(0)
#define VENUS_VBIF_AXI_HALT_ACK_TIMEOUT_US		500000

#define VIDC_VENUS0_WRAPPER_VBIF_REQ_PRIORITY \
	(VIDC_WRAPPER_BASE_OFFS + 0x20)