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

Commit 466bed2f authored by Suresh Vankadara's avatar Suresh Vankadara Committed by Alok Pandey
Browse files

msm: camera: icp: Add Power Collapse



Add support for ICP power collapse and IPE/BPS interframe
power collapse.

By default, interframe power collapse is enabled. If it needs to
be disabled, below command can be used. It must be done before
start of any use case.

adb shell "echo 0 > /sys/kernel/debug/camera_icp/icp_pc"

Change-Id: Idceec7b1b386cb894e7e074c4627d7b4dbcaf00a
Signed-off-by: default avatarSuresh Vankadara <svankada@codeaurora.org>
Signed-off-by: default avatarAlok Pandey <akumarpa@codeaurora.org>
parent 00f1431b
Loading
Loading
Loading
Loading
+13 −1
Original line number Diff line number Diff line
@@ -123,8 +123,9 @@ int hfi_set_debug_level(uint32_t lvl);
 * power collapse for IPE and BPS hardware.
 *
 * @enable: flag to enable/disable
 * @core_info: Core information to firmware
 */
int hfi_enable_ipe_bps_pc(bool enable);
int hfi_enable_ipe_bps_pc(bool enable, uint32_t core_info);

/**
 * hfi_cmd_ubwc_config() - UBWC configuration to firmware
@@ -132,4 +133,15 @@ int hfi_enable_ipe_bps_pc(bool enable);
 */
int hfi_cmd_ubwc_config(uint32_t *ubwc_cfg);

/**
 * cam_hfi_resume() - function to resume
 * @hfi_mem: hfi memory info
 * @icp_base: icp base address
 * @debug: debug flag
 *
 * Returns success(zero)/failure(non zero)
 */
int cam_hfi_resume(struct hfi_mem_info *hfi_mem,
	void __iomem *icp_base, bool debug);

#endif /* _HFI_INTF_H_ */
+9 −0
Original line number Diff line number Diff line
@@ -51,6 +51,15 @@
#define ICP_CSR_DBGSWENABLE                     (1 << 22)
#define ICP_CSR_A5_STATUS_WFI                   (1 << 7)

#define ICP_FLAG_A5_CTRL_DBG_EN                 (ICP_FLAG_CSR_WAKE_UP_EN|\
						ICP_FLAG_CSR_A5_EN|\
						ICP_CSR_EDBGRQ|\
						ICP_CSR_DBGSWENABLE)

#define ICP_FLAG_A5_CTRL_EN                     (ICP_FLAG_CSR_WAKE_UP_EN|\
						ICP_FLAG_CSR_A5_EN|\
						ICP_CSR_EN_CLKGATE_WFI)

/* start of Queue table and queues */
#define MAX_ICP_HFI_QUEUES                      4
#define ICP_QHDR_TX_TYPE_MASK                   0xFF000000
+2 −0
Original line number Diff line number Diff line
@@ -254,9 +254,11 @@ struct hfi_debug {
 * struct hfi_ipe_bps_pc
 * payload structure to configure HFI_PROPERTY_SYS_IPEBPS_PC
 * @enable: Flag to enable IPE, BPS interfrane power collapse
 * @core_info: Core information to firmware
 */
struct hfi_ipe_bps_pc {
	uint32_t enable;
	uint32_t core_info;
} __packed;

/**
+82 −7
Original line number Diff line number Diff line
@@ -40,6 +40,8 @@
#define HFI_VERSION_INFO_STEP_BMSK   0xFF
#define HFI_VERSION_INFO_STEP_SHFT  0

#define HFI_MAX_POLL_TRY 5

static struct hfi_info *g_hfi;
unsigned int g_icp_mmu_hdl;
static DEFINE_MUTEX(hfi_cmd_q_mutex);
@@ -248,7 +250,7 @@ int hfi_cmd_ubwc_config(uint32_t *ubwc_cfg)
	return 0;
}

int hfi_enable_ipe_bps_pc(bool enable)
int hfi_enable_ipe_bps_pc(bool enable, uint32_t core_info)
{
	uint8_t *prop;
	struct hfi_cmd_prop *dbg_prop;
@@ -267,6 +269,7 @@ int hfi_enable_ipe_bps_pc(bool enable)
	dbg_prop->num_prop = 1;
	dbg_prop->prop_data[0] = HFI_PROP_SYS_IPEBPS_PC;
	dbg_prop->prop_data[1] = enable;
	dbg_prop->prop_data[2] = core_info;

	hfi_write_cmd(prop);
	kfree(prop);
@@ -420,14 +423,28 @@ void cam_hfi_disable_cpu(void __iomem *icp_base)
{
	uint32_t data;
	uint32_t val;
	uint32_t try = 0;

	while (try < HFI_MAX_POLL_TRY) {
		data = cam_io_r(icp_base + HFI_REG_A5_CSR_A5_STATUS);
	/* Add waiting logic in case it is not idle */
	if (data & ICP_CSR_A5_STATUS_WFI) {
		CAM_DBG(CAM_HFI, "wfi status = %x\n", (int)data);

		if (data & ICP_CSR_A5_STATUS_WFI)
			break;
		/* Need to poll here to confirm that FW is going trigger wfi
		 * and Host can the proceed. No interrupt is expected from FW
		 * at this time.
		 */
		msleep(100);
		try++;
	}

	val = cam_io_r(icp_base + HFI_REG_A5_CSR_A5_CONTROL);
	val &= ~(ICP_FLAG_CSR_A5_EN | ICP_FLAG_CSR_WAKE_UP_EN);
	cam_io_w(val, icp_base + HFI_REG_A5_CSR_A5_CONTROL);
	}

	val = cam_io_r(icp_base + HFI_REG_A5_CSR_NSEC_RESET);
	cam_io_w(val, icp_base + HFI_REG_A5_CSR_NSEC_RESET);
}

void cam_hfi_enable_cpu(void __iomem *icp_base)
@@ -437,6 +454,64 @@ void cam_hfi_enable_cpu(void __iomem *icp_base)
	cam_io_w((uint32_t)0x10, icp_base + HFI_REG_A5_CSR_NSEC_RESET);
}

int cam_hfi_resume(struct hfi_mem_info *hfi_mem,
	void __iomem *icp_base, bool debug)
{
	int rc = 0;
	uint32_t data;
	uint32_t fw_version, status = 0;

	cam_hfi_enable_cpu(icp_base);
	g_hfi->csr_base = icp_base;

	rc = readw_poll_timeout((icp_base + HFI_REG_ICP_HOST_INIT_RESPONSE),
		status, status != ICP_INIT_RESP_SUCCESS, 15, 200);

	if (rc) {
		CAM_ERR(CAM_HFI, "timed out , status = %u", status);
		return -EINVAL;
	}

	fw_version = cam_io_r(icp_base + HFI_REG_FW_VERSION);
	CAM_DBG(CAM_HFI, "fw version : [%x]", fw_version);

	cam_io_w((uint32_t)INTR_ENABLE, icp_base + HFI_REG_A5_CSR_A2HOSTINTEN);

	if (debug) {
		cam_io_w_mb(ICP_FLAG_A5_CTRL_DBG_EN,
			(icp_base + HFI_REG_A5_CSR_A5_CONTROL));

		/* Barrier needed as next write should be done after
		 * sucessful previous write. Next write enable clock
		 * gating
		 */
		wmb();

		cam_io_w_mb((uint32_t)ICP_FLAG_A5_CTRL_EN,
			icp_base + HFI_REG_A5_CSR_A5_CONTROL);

	} else {
		cam_io_w_mb((uint32_t)ICP_FLAG_A5_CTRL_EN,
			icp_base + HFI_REG_A5_CSR_A5_CONTROL);
	}

	data = cam_io_r(icp_base + HFI_REG_A5_CSR_A5_STATUS);
	CAM_DBG(CAM_HFI, "wfi status = %x", (int)data);

	cam_io_w((uint32_t)hfi_mem->qtbl.iova, icp_base + HFI_REG_QTBL_PTR);
	cam_io_w((uint32_t)hfi_mem->shmem.iova,
		icp_base + HFI_REG_SHARED_MEM_PTR);
	cam_io_w((uint32_t)hfi_mem->shmem.len,
		icp_base + HFI_REG_SHARED_MEM_SIZE);
	cam_io_w((uint32_t)hfi_mem->sec_heap.iova,
		icp_base + HFI_REG_UNCACHED_HEAP_PTR);
	cam_io_w((uint32_t)hfi_mem->sec_heap.len,
		icp_base + HFI_REG_UNCACHED_HEAP_SIZE);

	cam_io_w((uint32_t)INTR_ENABLE, icp_base + HFI_REG_A5_CSR_A2HOSTINTEN);
	return rc;
}

int cam_hfi_init(uint8_t event_driven_mode, struct hfi_mem_info *hfi_mem,
		void __iomem *icp_base, bool debug)
{
+5 −0
Original line number Diff line number Diff line
@@ -422,6 +422,11 @@ int cam_a5_process_cmd(void *device_priv, uint32_t cmd_type,
	case CAM_ICP_A5_SEND_INIT:
		hfi_send_system_cmd(HFI_CMD_SYS_INIT, 0, 0);
		break;

	case CAM_ICP_A5_CMD_PC_PREP:
		hfi_send_system_cmd(HFI_CMD_SYS_PC_PREP, 0, 0);
		break;

	case CAM_ICP_A5_CMD_VOTE_CPAS: {
		struct cam_icp_cpas_vote *cpas_vote = cmd_args;

Loading