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

Commit 05187b95 authored by Tony Lijo Jose's avatar Tony Lijo Jose
Browse files

msm: camera: csiphy: Adding support of secure camera



Adding support for running secure and non secure session concurrently

Change-Id: If52c94a66a4706944c83cdaa522d6b56e030ebbe
Signed-off-by: default avatarTony Lijo Jose <tjose@codeaurora.org>
parent 2681192f
Loading
Loading
Loading
Loading
+141 −19
Original line number Diff line number Diff line
@@ -21,19 +21,23 @@
#define SCM_SVC_CAMERASS 0x18
#define SECURE_SYSCALL_ID 0x6

#define SECURE_SYSCALL_ID_2 0x7

static int csiphy_dump;
module_param(csiphy_dump, int, 0644);

static int cam_csiphy_notify_secure_mode(int phy, bool protect)
static int cam_csiphy_notify_secure_mode(struct csiphy_device *csiphy_dev,
	bool protect, int32_t offset)
{
	struct scm_desc desc = {0};

	if (offset >= CSIPHY_MAX_INSTANCES)
		return -EINVAL;
	desc.arginfo = SCM_ARGS(2, SCM_VAL, SCM_VAL);
	desc.args[0] = protect;
	desc.args[1] = phy;
	desc.args[1] = csiphy_dev->csiphy_cpas_cp_reg_mask[offset];

	CAM_DBG(CAM_CSIPHY, "phy : %d, protect : %d", phy, protect);
	if (scm_call2(SCM_SIP_FNID(SCM_SVC_CAMERASS, SECURE_SYSCALL_ID),
	if (scm_call2(SCM_SIP_FNID(SCM_SVC_CAMERASS, SECURE_SYSCALL_ID_2),
		&desc)) {
		CAM_ERR(CAM_CSIPHY, "scm call to hypervisor failed");
		return -EINVAL;
@@ -42,6 +46,27 @@ static int cam_csiphy_notify_secure_mode(int phy, bool protect)
	return 0;
}

static int32_t cam_csiphy_get_instance_offset(
	struct csiphy_device *csiphy_dev,
	int32_t dev_handle)
{
	int32_t i;

	if (csiphy_dev->acquire_count >
		CSIPHY_MAX_INSTANCES) {
		CAM_ERR(CAM_CSIPHY, "Invalid acquire count");
		return -EINVAL;
	}

	for (i = 0; i < csiphy_dev->acquire_count; i++) {
		if (dev_handle ==
			csiphy_dev->bridge_intf.device_hdl[i])
			break;
	}

	return i;
}

void cam_csiphy_query_cap(struct csiphy_device *csiphy_dev,
	struct cam_csiphy_query_cap *csiphy_cap)
{
@@ -75,6 +100,51 @@ void cam_csiphy_reset(struct csiphy_device *csiphy_dev)
	}
}

static int32_t cam_csiphy_update_secure_info(
	struct csiphy_device *csiphy_dev,
	struct cam_csiphy_info  *cam_cmd_csiphy_info,
	struct cam_config_dev_cmd *cfg_dev)
{
	uint32_t clock_lane, adj_lane_mask, temp;
	int32_t offset;

	if (csiphy_dev->acquire_count >=
		CSIPHY_MAX_INSTANCES) {
		CAM_ERR(CAM_CSIPHY, "Invalid acquire count");
		return -EINVAL;
	}

	offset = cam_csiphy_get_instance_offset(csiphy_dev,
		cfg_dev->dev_handle);
	if (offset < 0 || offset >= CSIPHY_MAX_INSTANCES) {
		CAM_ERR(CAM_CSIPHY, "Invalid offset");
		return -EINVAL;
	}

	if (cam_cmd_csiphy_info->combo_mode)
		clock_lane =
			csiphy_dev->ctrl_reg->csiphy_reg.csiphy_combo_clk_lane;
	else
		clock_lane =
			csiphy_dev->ctrl_reg->csiphy_reg.csiphy_clock_lane;

	adj_lane_mask = cam_cmd_csiphy_info->lane_mask & 0x1F &
		~clock_lane;
	temp = adj_lane_mask & (clock_lane - 1);
	adj_lane_mask =
		((adj_lane_mask & (~((clock_lane - 1)))) >> 1) | temp;

	csiphy_dev->csiphy_info.secure_mode[offset] = 1;

	csiphy_dev->csiphy_cpas_cp_reg_mask[offset] =
		adj_lane_mask << (csiphy_dev->soc_info.index *
		(CAM_CSIPHY_MAX_DPHY_LANES + CAM_CSIPHY_MAX_CPHY_LANES) +
		(!cam_cmd_csiphy_info->csiphy_3phase) *
		(CAM_CSIPHY_MAX_CPHY_LANES));

	return 0;
}

int32_t cam_cmd_buf_parser(struct csiphy_device *csiphy_dev,
	struct cam_config_dev_cmd *cfg_dev)
{
@@ -136,7 +206,10 @@ int32_t cam_cmd_buf_parser(struct csiphy_device *csiphy_dev,
		csiphy_dev->csiphy_info.settle_time =
			cam_cmd_csiphy_info->settle_time;
	csiphy_dev->csiphy_info.data_rate = cam_cmd_csiphy_info->data_rate;
	csiphy_dev->csiphy_info.secure_mode = cam_cmd_csiphy_info->secure_mode;

	if (cam_cmd_csiphy_info->secure_mode == 1)
		cam_csiphy_update_secure_info(csiphy_dev,
			cam_cmd_csiphy_info, cfg_dev);

	return rc;
}
@@ -347,6 +420,7 @@ int32_t cam_csiphy_config_dev(struct csiphy_device *csiphy_dev)
void cam_csiphy_shutdown(struct csiphy_device *csiphy_dev)
{
	struct cam_hw_soc_info *soc_info;
	int32_t i = 0;

	if (csiphy_dev->csiphy_state == CAM_CSIPHY_INIT)
		return;
@@ -354,14 +428,18 @@ void cam_csiphy_shutdown(struct csiphy_device *csiphy_dev)
	if (csiphy_dev->csiphy_state == CAM_CSIPHY_START) {
		soc_info = &csiphy_dev->soc_info;

		if (csiphy_dev->csiphy_info.secure_mode)
		for (i = 0; i < csiphy_dev->acquire_count; i++) {
			if (csiphy_dev->csiphy_info.secure_mode[i])
				cam_csiphy_notify_secure_mode(
				csiphy_dev->soc_info.index,
				CAM_SECURE_MODE_NON_SECURE);
					csiphy_dev,
					CAM_SECURE_MODE_NON_SECURE, i);

		csiphy_dev->csiphy_info.secure_mode =
			csiphy_dev->csiphy_info.secure_mode[i] =
				CAM_SECURE_MODE_NON_SECURE;

			csiphy_dev->csiphy_cpas_cp_reg_mask[i] = 0;
		}

		cam_csiphy_reset(csiphy_dev);
		cam_soc_util_disable_platform_resource(soc_info, true, true);

@@ -551,6 +629,16 @@ int32_t cam_csiphy_core_cfg(void *phy_dev,
	}
		break;
	case CAM_STOP_DEV: {
		int32_t offset, rc = 0;
		struct cam_start_stop_dev_cmd config;

		rc = copy_from_user(&config, (void __user *)cmd->handle,
					sizeof(config));
		if (rc < 0) {
			CAM_ERR(CAM_CSIPHY, "Failed copying from User");
			goto release_mutex;
		}

		if ((csiphy_dev->csiphy_state != CAM_CSIPHY_START) ||
			!csiphy_dev->start_dev_count) {
			CAM_ERR(CAM_CSIPHY, "Not in right state to stop : %d",
@@ -558,20 +646,38 @@ int32_t cam_csiphy_core_cfg(void *phy_dev,
			goto release_mutex;
		}

		offset = cam_csiphy_get_instance_offset(csiphy_dev,
			config.dev_handle);
		if (offset < 0 || offset >= CSIPHY_MAX_INSTANCES) {
			CAM_ERR(CAM_CSIPHY, "Invalid offset");
			goto release_mutex;
		}

		if (--csiphy_dev->start_dev_count) {
			CAM_DBG(CAM_CSIPHY, "Stop Dev ref Cnt: %d",
				csiphy_dev->start_dev_count);
			if (csiphy_dev->csiphy_info.secure_mode[offset])
				cam_csiphy_notify_secure_mode(
					csiphy_dev,
					CAM_SECURE_MODE_NON_SECURE, offset);

			csiphy_dev->csiphy_info.secure_mode[offset] =
				CAM_SECURE_MODE_NON_SECURE;
			csiphy_dev->csiphy_cpas_cp_reg_mask[offset] = 0;

			goto release_mutex;
		}

		if (csiphy_dev->csiphy_info.secure_mode)
		if (csiphy_dev->csiphy_info.secure_mode[offset])
			cam_csiphy_notify_secure_mode(
				csiphy_dev->soc_info.index,
				CAM_SECURE_MODE_NON_SECURE);
				csiphy_dev,
				CAM_SECURE_MODE_NON_SECURE, offset);

		csiphy_dev->csiphy_info.secure_mode =
		csiphy_dev->csiphy_info.secure_mode[offset] =
			CAM_SECURE_MODE_NON_SECURE;

		csiphy_dev->csiphy_cpas_cp_reg_mask[offset] = 0x0;

		rc = cam_csiphy_disable_hw(csiphy_dev);
		if (rc < 0)
			CAM_ERR(CAM_CSIPHY, "Failed in csiphy release");
@@ -645,12 +751,28 @@ int32_t cam_csiphy_core_cfg(void *phy_dev,
	case CAM_START_DEV: {
		struct cam_ahb_vote ahb_vote;
		struct cam_axi_vote axi_vote;
		struct cam_start_stop_dev_cmd config;
		int32_t offset;

		rc = copy_from_user(&config, (void __user *)cmd->handle,
			sizeof(config));
		if (rc < 0) {
			CAM_ERR(CAM_CSIPHY, "Failed copying from User");
			goto release_mutex;
		}

		if (csiphy_dev->csiphy_state == CAM_CSIPHY_START) {
			csiphy_dev->start_dev_count++;
			goto release_mutex;
		}

		offset = cam_csiphy_get_instance_offset(csiphy_dev,
			config.dev_handle);
		if (offset < 0 || offset >= CSIPHY_MAX_INSTANCES) {
			CAM_ERR(CAM_CSIPHY, "Invalid offset");
			goto release_mutex;
		}

		ahb_vote.type = CAM_VOTE_ABSOLUTE;
		ahb_vote.vote.level = CAM_SVS_VOTE;
		axi_vote.compressed_bw = CAM_CPAS_DEFAULT_AXI_BW;
@@ -663,12 +785,12 @@ int32_t cam_csiphy_core_cfg(void *phy_dev,
			goto release_mutex;
		}

		if (csiphy_dev->csiphy_info.secure_mode) {
		if (csiphy_dev->csiphy_info.secure_mode[offset] == 1) {
			rc = cam_csiphy_notify_secure_mode(
				csiphy_dev->soc_info.index,
				CAM_SECURE_MODE_SECURE);
				csiphy_dev,
				CAM_SECURE_MODE_SECURE, offset);
			if (rc < 0)
				csiphy_dev->csiphy_info.secure_mode =
				csiphy_dev->csiphy_info.secure_mode[offset] =
					CAM_SECURE_MODE_NON_SECURE;
		}

+16 −4
Original line number Diff line number Diff line
@@ -58,6 +58,11 @@
#define CSIPHY_SETTLE_CNT_HIGHER_BYTE    3
#define CSIPHY_DNP_PARAMS                4

#define CSIPHY_MAX_INSTANCES     2

#define CAM_CSIPHY_MAX_DPHY_LANES    4
#define CAM_CSIPHY_MAX_CPHY_LANES    3

#define ENABLE_IRQ false

#undef CDBG
@@ -101,6 +106,12 @@ struct csiphy_reg_parms_t {
	uint32_t csiphy_reset_array_size;
	uint32_t csiphy_2ph_config_array_size;
	uint32_t csiphy_3ph_config_array_size;
	uint32_t csiphy_cpas_cp_bits_per_phy;
	uint32_t csiphy_cpas_cp_is_interleaved;
	uint32_t csiphy_cpas_cp_2ph_offset;
	uint32_t csiphy_cpas_cp_3ph_offset;
	uint32_t csiphy_clock_lane;
	uint32_t csiphy_combo_clk_lane;
};

/**
@@ -111,9 +122,9 @@ struct csiphy_reg_parms_t {
 * @crm_cb: Callback API pointers
 */
struct intf_params {
	int32_t device_hdl[2];
	int32_t session_hdl[2];
	int32_t link_hdl[2];
	int32_t device_hdl[CSIPHY_MAX_INSTANCES];
	int32_t session_hdl[CSIPHY_MAX_INSTANCES];
	int32_t link_hdl[CSIPHY_MAX_INSTANCES];
	struct cam_req_mgr_kmd_ops ops;
	struct cam_req_mgr_crm_cb *crm_cb;
};
@@ -175,7 +186,7 @@ struct cam_csiphy_param {
	uint8_t     csiphy_3phase;
	uint8_t     combo_mode;
	uint8_t     lane_cnt;
	uint8_t     secure_mode;
	uint8_t     secure_mode[CSIPHY_MAX_INSTANCES];
	uint64_t    settle_time;
	uint64_t    settle_time_combo_sensor;
	uint64_t    data_rate;
@@ -231,6 +242,7 @@ struct csiphy_device {
	struct cam_hw_soc_info   soc_info;
	uint32_t cpas_handle;
	uint32_t config_count;
	uint64_t csiphy_cpas_cp_reg_mask[CSIPHY_MAX_INSTANCES];
};

#endif /* _CAM_CSIPHY_DEV_H_ */
+2 −0
Original line number Diff line number Diff line
@@ -23,6 +23,8 @@ struct csiphy_reg_parms_t csiphy_v1_0 = {
	.csiphy_reset_array_size = 5,
	.csiphy_2ph_config_array_size = 14,
	.csiphy_3ph_config_array_size = 19,
	.csiphy_clock_lane = 0x1,
	.csiphy_combo_clk_lane = 0x10,
};

struct csiphy_reg_t csiphy_common_reg_1_0[] = {