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

Commit 6657bc2e authored by Suresh Vankadara's avatar Suresh Vankadara
Browse files

msm: camera: icp: IPE and BPS interframe power collapse



Support is added for IPE and BPS interframe power
collapse. At the start of usecase transfer the control of
regualator to ICP hardware and get it back
at the end of usecase.

Change-Id: I561a5f71d4d5ce327bb1924638f2c7987d986a92
Signed-off-by: default avatarSuresh Vankadara <svankada@codeaurora.org>
parent 70eb2396
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -110,4 +110,13 @@ void cam_hfi_disable_cpu(void __iomem *icp_base);
 */
void cam_hfi_deinit(void);

/**
 * hfi_enable_ipe_bps_pc() - Enable interframe pc
 * Host sends a command to firmware to enable interframe
 * power collapse for IPE and BPS hardware.
 *
 * @enable: flag to enable/disable
 */
int hfi_enable_ipe_bps_pc(bool enable);

#endif /* _HFI_INTF_H_ */
+9 −0
Original line number Diff line number Diff line
@@ -158,6 +158,7 @@
#define HFI_PROP_SYS_DEBUG_CFG         (HFI_PROPERTY_ICP_COMMON_START + 0x1)
#define HFI_PROP_SYS_IMAGE_VER         (HFI_PROPERTY_ICP_COMMON_START + 0x3)
#define HFI_PROP_SYS_SUPPORTED         (HFI_PROPERTY_ICP_COMMON_START + 0x4)
#define HFI_PROP_SYS_IPEBPS_PC         (HFI_PROPERTY_ICP_COMMON_START + 0x5)

/* Capabilities reported at sys init */
#define HFI_CAPS_PLACEHOLDER_1         (HFI_COMMON_BASE + 0x1)
@@ -246,6 +247,14 @@ struct hfi_debug {
	uint32_t debug_mode;
} __packed;

/**
 * struct hfi_ipe_bps_pc
 * payload structure to configure HFI_PROPERTY_SYS_IPEBPS_PC
 * @enable: Flag to enable IPE, BPS interfrane power collapse
 */
struct hfi_ipe_bps_pc {
	uint32_t enable;
} __packed;

/**
 * struct hfi_cmd_sys_init
+26 −0
Original line number Diff line number Diff line
@@ -193,6 +193,32 @@ int hfi_read_message(uint32_t *pmsg, uint8_t q_id)
	return rc;
}

int hfi_enable_ipe_bps_pc(bool enable)
{
	uint8_t *prop;
	struct hfi_cmd_prop *dbg_prop;
	uint32_t size = 0;

	size = sizeof(struct hfi_cmd_prop) +
		sizeof(struct hfi_ipe_bps_pc);

	prop = kzalloc(size, GFP_KERNEL);
	if (!prop)
		return -ENOMEM;

	dbg_prop = (struct hfi_cmd_prop *)prop;
	dbg_prop->size = size;
	dbg_prop->pkt_type = HFI_CMD_SYS_SET_PROPERTY;
	dbg_prop->num_prop = 1;
	dbg_prop->prop_data[0] = HFI_PROP_SYS_IPEBPS_PC;
	dbg_prop->prop_data[1] = enable;

	hfi_write_cmd(prop);
	kfree(prop);

	return 0;
}

void hfi_send_system_cmd(uint32_t type, uint64_t data, uint32_t size)
{
	switch (type) {
+77 −0
Original line number Diff line number Diff line
@@ -133,6 +133,77 @@ int cam_bps_deinit_hw(void *device_priv,
	return rc;
}

static int cam_bps_handle_pc(struct cam_hw_info *bps_dev)
{
	struct cam_hw_soc_info *soc_info = NULL;
	struct cam_bps_device_core_info *core_info = NULL;
	struct cam_bps_device_hw_info *hw_info = NULL;
	int pwr_ctrl;
	int pwr_status;

	soc_info = &bps_dev->soc_info;
	core_info = (struct cam_bps_device_core_info *)bps_dev->core_info;
	hw_info = core_info->bps_hw_info;

	cam_cpas_reg_read(core_info->cpas_handle,
		CAM_CPAS_REG_CPASTOP, hw_info->pwr_ctrl,
		true, &pwr_ctrl);
	if (!(pwr_ctrl & BPS_COLLAPSE_MASK)) {
		cam_cpas_reg_read(core_info->cpas_handle,
			CAM_CPAS_REG_CPASTOP, hw_info->pwr_status,
			true, &pwr_status);

		cam_cpas_reg_write(core_info->cpas_handle,
			CAM_CPAS_REG_CPASTOP,
			hw_info->pwr_ctrl, true, 0x1);

		if ((pwr_status >> BPS_PWR_ON_MASK))
			return -EINVAL;
	}
	cam_bps_get_gdsc_control(soc_info);
	cam_cpas_reg_read(core_info->cpas_handle,
		CAM_CPAS_REG_CPASTOP, hw_info->pwr_ctrl, true,
		&pwr_ctrl);
	cam_cpas_reg_read(core_info->cpas_handle,
		CAM_CPAS_REG_CPASTOP, hw_info->pwr_status,
		true, &pwr_status);
	CAM_DBG(CAM_ICP, "pwr_ctrl = %x pwr_status = %x",
		pwr_ctrl, pwr_status);

	return 0;
}

static int cam_bps_handle_resume(struct cam_hw_info *bps_dev)
{
	struct cam_hw_soc_info *soc_info = NULL;
	struct cam_bps_device_core_info *core_info = NULL;
	struct cam_bps_device_hw_info *hw_info = NULL;
	int pwr_ctrl;
	int pwr_status;
	int rc = 0;

	soc_info = &bps_dev->soc_info;
	core_info = (struct cam_bps_device_core_info *)bps_dev->core_info;
	hw_info = core_info->bps_hw_info;

	cam_cpas_reg_read(core_info->cpas_handle,
		CAM_CPAS_REG_CPASTOP, hw_info->pwr_ctrl, true, &pwr_ctrl);
	if (pwr_ctrl & BPS_COLLAPSE_MASK) {
		CAM_ERR(CAM_ICP, "BPS: resume failed : %d", pwr_ctrl);
		return -EINVAL;
	}

	rc = cam_bps_transfer_gdsc_control(soc_info);
	cam_cpas_reg_read(core_info->cpas_handle,
		CAM_CPAS_REG_CPASTOP, hw_info->pwr_ctrl, true, &pwr_ctrl);
	cam_cpas_reg_read(core_info->cpas_handle,
		CAM_CPAS_REG_CPASTOP, hw_info->pwr_status, true, &pwr_status);
	CAM_DBG(CAM_ICP, "pwr_ctrl = %x pwr_status = %x",
		pwr_ctrl, pwr_status);

	return rc;
}

int cam_bps_process_cmd(void *device_priv, uint32_t cmd_type,
	void *cmd_args, uint32_t arg_size)
{
@@ -192,6 +263,12 @@ int cam_bps_process_cmd(void *device_priv, uint32_t cmd_type,
			core_info->cpas_start = false;
		}
		break;
	case CAM_ICP_BPS_CMD_POWER_COLLAPSE:
		rc = cam_bps_handle_pc(bps_dev);
		break;
	case CAM_ICP_BPS_CMD_POWER_RESUME:
		rc = cam_bps_handle_resume(bps_dev);
		break;
	default:
		break;
	}
+6 −0
Original line number Diff line number Diff line
@@ -19,7 +19,13 @@
#include <linux/platform_device.h>
#include <linux/dma-buf.h>

#define BPS_COLLAPSE_MASK 0x1
#define BPS_PWR_ON_MASK   0x2

struct cam_bps_device_hw_info {
	uint32_t hw_idx;
	uint32_t pwr_ctrl;
	uint32_t pwr_status;
	uint32_t reserved;
};

Loading