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

Commit fb0190d8 authored by Viswanadha Raju Thotakura's avatar Viswanadha Raju Thotakura
Browse files

msm: camera: Changes for secure camera



Add support for concurrent secure and non secure camera.

Change-Id: I455e6cd3c3239f35cebd1f9e05a62fd3e12e5ef8
Signed-off-by: default avatarViswanadha Raju Thotakura <viswanad@codeaurora.org>
parent dcc70d2c
Loading
Loading
Loading
Loading
+3 −23
Original line number Diff line number Diff line
@@ -2680,7 +2680,6 @@ static int cam_icp_mgr_hw_close(void *hw_priv, void *hw_close_args)

	cam_icp_free_hfi_mem();
	hw_mgr->fw_download = false;
	hw_mgr->secure_mode = CAM_SECURE_MODE_NON_SECURE;

	CAM_DBG(CAM_ICP, "Exit");
	return rc;
@@ -3934,7 +3933,6 @@ static int cam_icp_mgr_release_hw(void *hw_mgr_priv, void *release_hw_args)
		CAM_DBG(CAM_ICP, "Last Release");
		cam_icp_mgr_icp_power_collapse(hw_mgr);
		cam_icp_hw_mgr_reset_clk_info(hw_mgr);
		hw_mgr->secure_mode = CAM_SECURE_MODE_NON_SECURE;
		rc = cam_ipe_bps_deint(hw_mgr);
	}
	mutex_unlock(&hw_mgr->hw_mgr_mutex);
@@ -4066,47 +4064,29 @@ static int cam_icp_get_acquire_info(struct cam_icp_hw_mgr *hw_mgr,
		return -EFAULT;
	}

	if (!hw_mgr->ctxt_cnt) {
		hw_mgr->secure_mode = icp_dev_acquire_info.secure_mode;
	} else {
		if (hw_mgr->secure_mode != icp_dev_acquire_info.secure_mode) {
			CAM_ERR(CAM_ICP,
				"secure mode mismatch driver:%d, context:%d",
				hw_mgr->secure_mode,
				icp_dev_acquire_info.secure_mode);
			return -EINVAL;
		}
	}

	acquire_size = sizeof(struct cam_icp_acquire_dev_info) +
		((icp_dev_acquire_info.num_out_res - 1) *
		sizeof(struct cam_icp_res_info));
	ctx_data->icp_dev_acquire_info = kzalloc(acquire_size, GFP_KERNEL);
	if (!ctx_data->icp_dev_acquire_info) {
		if (!hw_mgr->ctxt_cnt)
			hw_mgr->secure_mode = CAM_SECURE_MODE_NON_SECURE;
	if (!ctx_data->icp_dev_acquire_info)
		return -ENOMEM;
	}

	if (copy_from_user(ctx_data->icp_dev_acquire_info,
		(void __user *)args->acquire_info, acquire_size)) {
		CAM_ERR(CAM_ICP, "Failed in acquire: size = %d", acquire_size);
		if (!hw_mgr->ctxt_cnt)
			hw_mgr->secure_mode = CAM_SECURE_MODE_NON_SECURE;
		kfree(ctx_data->icp_dev_acquire_info);
		ctx_data->icp_dev_acquire_info = NULL;
		return -EFAULT;
	}

	CAM_DBG(CAM_ICP, "%x %x %x %x %x %x %x %u",
	CAM_DBG(CAM_ICP, "%x %x %x %x %x %x %x",
		ctx_data->icp_dev_acquire_info->dev_type,
		ctx_data->icp_dev_acquire_info->in_res.format,
		ctx_data->icp_dev_acquire_info->in_res.width,
		ctx_data->icp_dev_acquire_info->in_res.height,
		ctx_data->icp_dev_acquire_info->in_res.fps,
		ctx_data->icp_dev_acquire_info->num_out_res,
		ctx_data->icp_dev_acquire_info->scratch_mem_size,
		hw_mgr->secure_mode);
		ctx_data->icp_dev_acquire_info->scratch_mem_size);

	p_icp_out = ctx_data->icp_dev_acquire_info->out_res;
	for (i = 0; i < icp_dev_acquire_info.num_out_res; i++)
+14 −0
Original line number Diff line number Diff line
@@ -990,6 +990,7 @@ static int cam_ife_mgr_acquire_cid_res(
	struct cam_ife_hw_mgr_res           *cid_res_temp, *cid_res_iterator;
	struct cam_csid_hw_reserve_resource_args  csid_acquire;
	uint32_t acquired_cnt = 0;
	struct cam_isp_out_port_info        *out_port = NULL;

	ife_hw_mgr = ife_ctx->hw_mgr;
	*cid_res = NULL;
@@ -1007,6 +1008,9 @@ static int cam_ife_mgr_acquire_cid_res(
	csid_acquire.res_id =  csid_path;
	CAM_DBG(CAM_ISP, "path %d", csid_path);

	if (in_port->num_out_res)
		out_port = &(in_port->data[0]);

	/* Try acquiring CID resource from previously acquired HW */
	list_for_each_entry(cid_res_iterator, &ife_ctx->res_list_ife_cid,
		list) {
@@ -1015,6 +1019,12 @@ static int cam_ife_mgr_acquire_cid_res(
			if (!cid_res_iterator->hw_res[i])
				continue;

			if (cid_res_iterator->is_secure == 1 ||
				(cid_res_iterator->is_secure == 0 &&
				in_port->num_out_res &&
				out_port->secure_mode == 1))
				continue;

			hw_intf = cid_res_iterator->hw_res[i]->hw_intf;
			rc = hw_intf->hw_ops.reserve(hw_intf->hw_priv,
				&csid_acquire, sizeof(csid_acquire));
@@ -1084,6 +1094,10 @@ static int cam_ife_mgr_acquire_cid_res(
	/* CID(DT_ID) value of acquire device, require for path */
	cid_res_temp->res_id = csid_acquire.node_res->res_id;
	cid_res_temp->is_dual_vfe = in_port->usage_type;

	if (in_port->num_out_res)
		cid_res_temp->is_secure = out_port->secure_mode;

	cam_ife_hw_mgr_put_res(&ife_ctx->res_list_ife_cid, cid_res);

	/*
+2 −0
Original line number Diff line number Diff line
@@ -50,6 +50,7 @@ enum cam_ife_hw_mgr_res_type {
 * @parent:              point to the parent resource node.
 * @children:            point to the children resource nodes
 * @child_num:           numbe of the child resource node.
 * @is_secure            informs whether the resource is in secure mode or not
 *
 */
struct cam_ife_hw_mgr_res {
@@ -63,6 +64,7 @@ struct cam_ife_hw_mgr_res {
	struct cam_ife_hw_mgr_res       *parent;
	struct cam_ife_hw_mgr_res       *child[CAM_IFE_HW_OUT_RES_MAX];
	uint32_t                         num_children;
	uint32_t                         is_secure;
};


+151 −21
Original line number Diff line number Diff line
@@ -20,20 +20,29 @@

#define SCM_SVC_CAMERASS 0x18
#define SECURE_SYSCALL_ID 0x6
#define SECURE_SYSCALL_ID_2 0x7

#define LANE_MASK_2PH 0x1F
#define LANE_MASK_3PH 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) {
		CAM_ERR(CAM_CSIPHY, "Invalid CSIPHY offset");
		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 +51,27 @@ static int cam_csiphy_notify_secure_mode(int phy, bool protect)
	return 0;
}

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 +105,54 @@ void cam_csiphy_reset(struct csiphy_device *csiphy_dev)
	}
}

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_2ph_combo_ck_ln;
	else
		clock_lane =
			csiphy_dev->ctrl_reg->csiphy_reg.csiphy_2ph_clock_lane;

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

	if (cam_cmd_csiphy_info->csiphy_3phase)
		adj_lane_mask = cam_cmd_csiphy_info->lane_mask & LANE_MASK_3PH;

	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 +214,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;
}
@@ -234,7 +315,7 @@ int32_t cam_csiphy_config_dev(struct csiphy_device *csiphy_dev)
		cfg_size =
		csiphy_dev->ctrl_reg->csiphy_reg.csiphy_2ph_config_array_size;

		lane_mask = csiphy_dev->csiphy_info.lane_mask & 0x1f;
		lane_mask = csiphy_dev->csiphy_info.lane_mask & LANE_MASK_2PH;
		for (i = 0; i < MAX_DPHY_DATA_LN; i++) {
			if (mask == 0x2) {
				if (lane_mask & mask)
@@ -263,7 +344,7 @@ int32_t cam_csiphy_config_dev(struct csiphy_device *csiphy_dev)
		cfg_size =
		csiphy_dev->ctrl_reg->csiphy_reg.csiphy_3ph_config_array_size;

		lane_mask = csiphy_dev->csiphy_info.lane_mask & 0x7;
		lane_mask = csiphy_dev->csiphy_info.lane_mask & LANE_MASK_3PH;
		mask = lane_mask;
		while (mask != 0) {
			temp = (i << 1)+1;
@@ -367,6 +448,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;
@@ -374,14 +456,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);

@@ -571,6 +657,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",
@@ -578,20 +674,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");
@@ -665,12 +779,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;
@@ -683,12 +813,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;
		}

+29 −4
Original line number Diff line number Diff line
@@ -60,6 +60,11 @@
#define CSIPHY_2PH_REGS                  5
#define CSIPHY_3PH_REGS                  6

#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
@@ -89,6 +94,15 @@ enum cam_csiphy_state {
 * @csiphy_version: CSIPhy Version
 * @csiphy_common_array_size: CSIPhy common array size
 * @csiphy_reset_array_size: CSIPhy reset array size
 * @csiphy_2ph_config_array_size: 2ph settings size
 * @csiphy_3ph_config_array_size: 3ph settings size
 * @csiphy_cpas_cp_bits_per_phy: CP bits per phy
 * @csiphy_cpas_cp_is_interleaved: checks whether cp bits
 *      are interleaved or not
 * @csiphy_cpas_cp_2ph_offset: cp register 2ph offset
 * @csiphy_cpas_cp_3ph_offset: cp register 3ph offset
 * @csiphy_2ph_clock_lane: clock lane in 2ph
 * @csiphy_2ph_combo_ck_ln: clk lane in combo 2ph
 */
struct csiphy_reg_parms_t {
/*MIPI CSI PHY registers*/
@@ -103,6 +117,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_2ph_clock_lane;
	uint32_t csiphy_2ph_combo_ck_ln;
};

/**
@@ -113,9 +133,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;
};
@@ -177,7 +197,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;
@@ -208,6 +228,10 @@ struct cam_csiphy_param {
 * @is_acquired_dev_combo_mode:
 *    Flag that mentions whether already acquired
 *   device is for combo mode
 * @soc_info: SOC information
 * @cpas_handle: CPAS handle
 * @config_count: Config reg count
 * @csiphy_cpas_cp_reg_mask: CP reg mask for phy instance
 */
struct csiphy_device {
	struct mutex mutex;
@@ -233,6 +257,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_ */
Loading