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

Commit 24f712e6 authored by Ravikishore Pampana's avatar Ravikishore Pampana
Browse files

msm: camera: isp: Handle more than one isp init packet



The new design requires ISP to handle multiple INIT packet when it comes.
The change adds the logic to merge the multiple INIT packet into one
single packet.

Change-Id: I90e35da09239b73517f8d34e1e01032333edbb03
Signed-off-by: default avatarRavikishore Pampana <rpampana@codeaurora.org>
Signed-off-by: default avatarJing Zhou <jzhou70@codeaurora.org>
parent 789139b1
Loading
Loading
Loading
Loading
+102 −16
Original line number Original line Diff line number Diff line
@@ -66,6 +66,73 @@ static int __cam_isp_ctx_enqueue_request_in_order(
	return 0;
	return 0;
}
}


static int __cam_isp_ctx_enqueue_init_request(
	struct cam_context *ctx, struct cam_ctx_request *req)
{
	int rc = 0;
	struct cam_ctx_request           *req_old;
	struct cam_isp_ctx_req           *req_isp_old;
	struct cam_isp_ctx_req           *req_isp_new;

	spin_lock_bh(&ctx->lock);
	if (list_empty(&ctx->pending_req_list)) {
		list_add_tail(&req->list, &ctx->pending_req_list);
		CAM_DBG(CAM_ISP, "INIT packet added req id= %d",
			req->request_id);
		goto end;
	}

	req_old = list_first_entry(&ctx->pending_req_list,
		struct cam_ctx_request, list);
	req_isp_old = (struct cam_isp_ctx_req *) req_old->req_priv;
	req_isp_new = (struct cam_isp_ctx_req *) req->req_priv;
	if (req_isp_old->packet_opcode_type == CAM_ISP_PACKET_INIT_DEV) {
		if ((req_isp_old->num_cfg + req_isp_new->num_cfg) >=
			CAM_ISP_CTX_CFG_MAX) {
			CAM_WARN(CAM_ISP, "Can not merge INIT pkt");
			rc = -ENOMEM;
		}

		if (req_isp_old->num_fence_map_out != 0 ||
			req_isp_old->num_fence_map_in != 0) {
			CAM_WARN(CAM_ISP, "Invalid INIT pkt sequence");
			rc = -EINVAL;
		}

		if (!rc) {
			memcpy(req_isp_old->fence_map_out,
				req_isp_new->fence_map_out,
				sizeof(req_isp_new->fence_map_out[0])*
				req_isp_new->num_fence_map_out);
			req_isp_old->num_fence_map_out =
				req_isp_new->num_fence_map_out;

			memcpy(req_isp_old->fence_map_in,
				req_isp_new->fence_map_in,
				sizeof(req_isp_new->fence_map_in[0])*
				req_isp_new->num_fence_map_in);
			req_isp_old->num_fence_map_in =
				req_isp_new->num_fence_map_in;

			memcpy(&req_isp_old->cfg[req_isp_old->num_cfg],
				req_isp_new->cfg,
				sizeof(req_isp_new->cfg[0])*
				req_isp_new->num_cfg);
			req_isp_old->num_cfg += req_isp_new->num_cfg;

			list_add_tail(&req->list, &ctx->free_req_list);
		}
	} else {
		CAM_WARN(CAM_ISP,
			"Received Update pkt before INIT pkt. req_id= %lld",
			req->request_id);
		rc = -EINVAL;
	}
end:
	spin_unlock_bh(&ctx->lock);
	return rc;
}

static const char *__cam_isp_resource_handle_id_to_type
static const char *__cam_isp_resource_handle_id_to_type
	(uint32_t resource_handle)
	(uint32_t resource_handle)
{
{
@@ -1627,6 +1694,7 @@ static int __cam_isp_ctx_config_dev_in_top_state(
	struct cam_req_mgr_add_request    add_req;
	struct cam_req_mgr_add_request    add_req;
	struct cam_isp_context           *ctx_isp =
	struct cam_isp_context           *ctx_isp =
		(struct cam_isp_context *) ctx->ctx_priv;
		(struct cam_isp_context *) ctx->ctx_priv;
	struct cam_isp_prepare_hw_update_data    hw_update_data;


	CAM_DBG(CAM_ISP, "get free request object......");
	CAM_DBG(CAM_ISP, "get free request object......");


@@ -1677,6 +1745,7 @@ static int __cam_isp_ctx_config_dev_in_top_state(
	cfg.max_in_map_entries = CAM_ISP_CTX_RES_MAX;
	cfg.max_in_map_entries = CAM_ISP_CTX_RES_MAX;
	cfg.out_map_entries = req_isp->fence_map_out;
	cfg.out_map_entries = req_isp->fence_map_out;
	cfg.in_map_entries = req_isp->fence_map_in;
	cfg.in_map_entries = req_isp->fence_map_in;
	cfg.priv  = &hw_update_data;


	CAM_DBG(CAM_ISP, "try to prepare config packet......");
	CAM_DBG(CAM_ISP, "try to prepare config packet......");


@@ -1691,6 +1760,7 @@ static int __cam_isp_ctx_config_dev_in_top_state(
	req_isp->num_fence_map_out = cfg.num_out_map_entries;
	req_isp->num_fence_map_out = cfg.num_out_map_entries;
	req_isp->num_fence_map_in = cfg.num_in_map_entries;
	req_isp->num_fence_map_in = cfg.num_in_map_entries;
	req_isp->num_acked = 0;
	req_isp->num_acked = 0;
	req_isp->packet_opcode_type = hw_update_data.packet_opcode_type;


	CAM_DBG(CAM_ISP, "num_entry: %d, num fence out: %d, num fence in: %d",
	CAM_DBG(CAM_ISP, "num_entry: %d, num fence out: %d, num fence in: %d",
		req_isp->num_cfg, req_isp->num_fence_map_out,
		req_isp->num_cfg, req_isp->num_fence_map_out,
@@ -1699,6 +1769,19 @@ static int __cam_isp_ctx_config_dev_in_top_state(
	req->request_id = packet->header.request_id;
	req->request_id = packet->header.request_id;
	req->status = 1;
	req->status = 1;


	CAM_DBG(CAM_ISP, "Packet request id 0x%llx packet opcode:%d",
		packet->header.request_id, req_isp->packet_opcode_type);

	if (req_isp->packet_opcode_type == CAM_ISP_PACKET_INIT_DEV) {
		if (ctx->state < CAM_CTX_ACTIVATED) {
			rc = __cam_isp_ctx_enqueue_init_request(ctx, req);
			if (rc)
				CAM_ERR(CAM_ISP, "Enqueue INIT pkt failed");
		} else {
			rc = -EINVAL;
			CAM_ERR(CAM_ISP, "Recevied INIT pkt in wrong state");
		}
	} else {
		if (ctx->state >= CAM_CTX_READY && ctx->ctx_crm_intf->add_req) {
		if (ctx->state >= CAM_CTX_READY && ctx->ctx_crm_intf->add_req) {
			add_req.link_hdl = ctx->link_hdl;
			add_req.link_hdl = ctx->link_hdl;
			add_req.dev_hdl  = ctx->dev_hdl;
			add_req.dev_hdl  = ctx->dev_hdl;
@@ -1706,16 +1789,19 @@ static int __cam_isp_ctx_config_dev_in_top_state(
			add_req.skip_before_applying = 0;
			add_req.skip_before_applying = 0;
			rc = ctx->ctx_crm_intf->add_req(&add_req);
			rc = ctx->ctx_crm_intf->add_req(&add_req);
			if (rc) {
			if (rc) {
			CAM_ERR(CAM_ISP, "Error: Adding request id=%llu",
				CAM_ERR(CAM_ISP, "Add req failed: req id=%llu",
					req->request_id);
					req->request_id);
				goto free_req;
			} else {
				__cam_isp_ctx_enqueue_request_in_order(
					ctx, req);
			}
		} else {
			rc = -EINVAL;
			CAM_ERR(CAM_ISP, "Recevied Update in wrong state");
		}
		}
	}
	}

	if (rc)
	CAM_DBG(CAM_ISP, "Packet request id 0x%llx",
		goto free_req;
		packet->header.request_id);

	__cam_isp_ctx_enqueue_request_in_order(ctx, req);


	CAM_DBG(CAM_ISP, "Preprocessing Config %lld successful",
	CAM_DBG(CAM_ISP, "Preprocessing Config %lld successful",
		req->request_id);
		req->request_id);
+3 −0
Original line number Original line Diff line number Diff line
@@ -81,6 +81,8 @@ struct cam_isp_ctx_irq_ops {
 *                         the request has been completed.
 *                         the request has been completed.
 * @bubble_report:         Flag to track if bubble report is active on
 * @bubble_report:         Flag to track if bubble report is active on
 *                         current request
 *                         current request
 * @packet_opcode_type:    Request packet opcode type,
 *                         ie INIT packet or update packet
 *
 *
 */
 */
struct cam_isp_ctx_req {
struct cam_isp_ctx_req {
@@ -94,6 +96,7 @@ struct cam_isp_ctx_req {
	uint32_t                         num_fence_map_in;
	uint32_t                         num_fence_map_in;
	uint32_t                         num_acked;
	uint32_t                         num_acked;
	int32_t                          bubble_report;
	int32_t                          bubble_report;
	uint32_t                         packet_opcode_type;
};
};


/**
/**
+12 −6
Original line number Original line Diff line number Diff line
@@ -2354,6 +2354,7 @@ static int cam_ife_mgr_prepare_hw_update(void *hw_mgr_priv,
	struct cam_kmd_buf_info                  kmd_buf;
	struct cam_kmd_buf_info                  kmd_buf;
	uint32_t                                 i;
	uint32_t                                 i;
	bool                                     fill_fence = true;
	bool                                     fill_fence = true;
	struct cam_isp_prepare_hw_update_data   *prepare_hw_data;


	if (!hw_mgr_priv || !prepare_hw_update_args) {
	if (!hw_mgr_priv || !prepare_hw_update_args) {
		CAM_ERR(CAM_ISP, "Invalid args");
		CAM_ERR(CAM_ISP, "Invalid args");
@@ -2439,9 +2440,14 @@ static int cam_ife_mgr_prepare_hw_update(void *hw_mgr_priv,
	 * bits to get the type of operation since UMD definition
	 * bits to get the type of operation since UMD definition
	 * of op_code has some difference from KMD.
	 * of op_code has some difference from KMD.
	 */
	 */
	prepare_hw_data = (struct cam_isp_prepare_hw_update_data  *)
		prepare->priv;
	if (((prepare->packet->header.op_code + 1) & 0xF) ==
	if (((prepare->packet->header.op_code + 1) & 0xF) ==
		CAM_ISP_PACKET_INIT_DEV)
		CAM_ISP_PACKET_INIT_DEV) {
		prepare_hw_data->packet_opcode_type = CAM_ISP_PACKET_INIT_DEV;
		goto end;
		goto end;
	} else
		prepare_hw_data->packet_opcode_type = CAM_ISP_PACKET_UPDATE_DEV;


	/* add reg update commands */
	/* add reg update commands */
	for (i = 0; i < ctx->num_base; i++) {
	for (i = 0; i < ctx->num_base; i++) {
+12 −0
Original line number Original line Diff line number Diff line
@@ -46,6 +46,18 @@ enum cam_isp_hw_err_type {
	CAM_ISP_HW_ERROR_MAX,
	CAM_ISP_HW_ERROR_MAX,
};
};


/**
 * struct cam_isp_prepare_hw_update_data - hw prepare data
 *
 * @packet_opcode_type:     Packet header opcode in the packet header
 *                   this opcode defines, packet is init packet or
 *                   update packet
 *
 */
struct cam_isp_prepare_hw_update_data {
	uint32_t      packet_opcode_type;
};



/**
/**
 * struct cam_isp_hw_sof_event_data - Event payload for CAM_HW_EVENT_SOF
 * struct cam_isp_hw_sof_event_data - Event payload for CAM_HW_EVENT_SOF