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

Commit 1d1edb70 authored by Alok Chauhan's avatar Alok Chauhan
Browse files

msm: camera: sync: Add SYNC_V4L_EVENT_V2 support in sync driver



Add SYNC_V4L_EVENT_V2 support in sync driver. As part of this
change, added the reason code field as part of sync event header.
This failure reason code is filled by camera kernel driver and
propagate to userspace.

CRs-Fixed: 2750553
Change-Id: I206d0d51c38cfe4214814b89d241f51c1f50605b
Signed-off-by: default avatarAlok Chauhan <alokc@codeaurora.org>
parent f64d8b76
Loading
Loading
Loading
Loading
+8 −4
Original line number Diff line number Diff line
@@ -98,7 +98,8 @@ int cam_context_buf_done_from_hw(struct cam_context *ctx,
	for (j = 0; j < req->num_out_map_entries; j++) {
		CAM_DBG(CAM_REQ, "fence %d signal with %d",
			req->out_map_entries[j].sync_id, result);
		cam_sync_signal(req->out_map_entries[j].sync_id, result);
		cam_sync_signal(req->out_map_entries[j].sync_id, result,
			done->evt_param);
		req->out_map_entries[j].sync_id = -1;
	}

@@ -661,7 +662,8 @@ int32_t cam_context_flush_ctx_to_hw(struct cam_context *ctx)
			if (req->out_map_entries[i].sync_id != -1) {
				rc = cam_sync_signal(
					req->out_map_entries[i].sync_id,
					CAM_SYNC_STATE_SIGNALED_CANCEL);
					CAM_SYNC_STATE_SIGNALED_CANCEL,
					CAM_SYNC_EVENT_FLUSH);
				if (rc == -EALREADY) {
					CAM_ERR(CAM_CTXT,
					"Req: %llu already signalled, sync_id:%d",
@@ -733,7 +735,8 @@ int32_t cam_context_flush_ctx_to_hw(struct cam_context *ctx)
			if (req->out_map_entries[i].sync_id != -1) {
				rc = cam_sync_signal(
					req->out_map_entries[i].sync_id,
					CAM_SYNC_STATE_SIGNALED_CANCEL);
					CAM_SYNC_STATE_SIGNALED_CANCEL,
					CAM_SYNC_EVENT_FLUSH);
				if (rc == -EALREADY) {
					CAM_ERR(CAM_CTXT,
						"Req: %llu already signalled ctx: %pK dev_name: %s dev_handle: %d ctx_state: %d",
@@ -846,7 +849,8 @@ int32_t cam_context_flush_req_to_hw(struct cam_context *ctx,
					req->out_map_entries[i].sync_id;
				if (sync_id != -1) {
					rc = cam_sync_signal(sync_id,
						CAM_SYNC_STATE_SIGNALED_CANCEL);
						CAM_SYNC_STATE_SIGNALED_CANCEL,
						CAM_SYNC_EVENT_FLUSH);
					if (rc == -EALREADY) {
						CAM_ERR(CAM_CTXT,
						"Req: %llu already signalled, sync_id:%d",
+2 −0
Original line number Diff line number Diff line
@@ -90,6 +90,7 @@ struct cam_hw_fence_map_entry {
 * @resrouce_handle:       list of the resource handle
 * @timestamp:             time stamp
 * @request_id:            request identifier
 * @evt_param:             event parameter
 *
 */
struct cam_hw_done_event_data {
@@ -97,6 +98,7 @@ struct cam_hw_done_event_data {
	uint32_t           resource_handle[CAM_NUM_OUT_PER_COMP_IRQ_MAX];
	struct timeval     timestamp;
	uint64_t           request_id;
	uint32_t           evt_param;
};

/**
+10 −5
Original line number Diff line number Diff line
@@ -182,7 +182,8 @@ static int __cam_custom_ctx_frame_done(
		}

		rc = cam_sync_signal(req_custom->fence_map_out[j].sync_id,
				CAM_SYNC_STATE_SIGNALED_SUCCESS);
				CAM_SYNC_STATE_SIGNALED_SUCCESS,
				CAM_SYNC_EVENT_SUCCESS);
		if (rc)
			CAM_ERR(CAM_CUSTOM, "Sync failed with rc = %d", rc);

@@ -368,7 +369,8 @@ static int __cam_custom_ctx_flush_req(struct cam_context *ctx,
					req_custom->fence_map_out[i].sync_id);
				rc = cam_sync_signal(
					req_custom->fence_map_out[i].sync_id,
					CAM_SYNC_STATE_SIGNALED_CANCEL);
					CAM_SYNC_STATE_SIGNALED_CANCEL,
					CAM_SYNC_EVENT_FLUSH);
				if (rc)
					CAM_ERR_RATE_LIMIT(CAM_CUSTOM,
						"signal fence failed\n");
@@ -543,7 +545,8 @@ static int __cam_custom_stop_dev_core(
			if (req_custom->fence_map_out[i].sync_id != -1) {
				cam_sync_signal(
					req_custom->fence_map_out[i].sync_id,
					CAM_SYNC_STATE_SIGNALED_CANCEL);
					CAM_SYNC_STATE_SIGNALED_CANCEL,
					CAM_SYNC_EVENT_STOP);
			}
		list_add_tail(&req->list, &ctx->free_req_list);
	}
@@ -559,7 +562,8 @@ static int __cam_custom_stop_dev_core(
			if (req_custom->fence_map_out[i].sync_id != -1) {
				cam_sync_signal(
					req_custom->fence_map_out[i].sync_id,
					CAM_SYNC_STATE_SIGNALED_CANCEL);
					CAM_SYNC_STATE_SIGNALED_CANCEL,
					CAM_SYNC_EVENT_STOP);
			}
		list_add_tail(&req->list, &ctx->free_req_list);
	}
@@ -575,7 +579,8 @@ static int __cam_custom_stop_dev_core(
			if (req_custom->fence_map_out[i].sync_id != -1) {
				cam_sync_signal(
					req_custom->fence_map_out[i].sync_id,
					CAM_SYNC_STATE_SIGNALED_CANCEL);
					CAM_SYNC_STATE_SIGNALED_CANCEL,
					CAM_SYNC_EVENT_STOP);
			}
		list_add_tail(&req->list, &ctx->free_req_list);
	}
+46 −13
Original line number Diff line number Diff line
@@ -813,7 +813,8 @@ static int __cam_isp_ctx_handle_buf_done_for_req_list(
			for (i = 0; i < req_isp->num_fence_map_out; i++)
				rc = cam_sync_signal(
					req_isp->fence_map_out[i].sync_id,
					CAM_SYNC_STATE_SIGNALED_ERROR);
					CAM_SYNC_STATE_SIGNALED_ERROR,
					CAM_SYNC_ISP_EVENT_BUBBLE);

			list_add_tail(&req->list, &ctx->free_req_list);
			CAM_DBG(CAM_REQ,
@@ -935,7 +936,8 @@ static int __cam_isp_ctx_handle_buf_done_for_request(
				ctx->ctx_id);

			rc = cam_sync_signal(req_isp->fence_map_out[j].sync_id,
				CAM_SYNC_STATE_SIGNALED_SUCCESS);
				CAM_SYNC_STATE_SIGNALED_SUCCESS,
				CAM_SYNC_EVENT_SUCCESS);
			if (rc)
				CAM_DBG(CAM_ISP, "Sync failed with rc = %d",
					 rc);
@@ -948,7 +950,8 @@ static int __cam_isp_ctx_handle_buf_done_for_request(
				ctx->ctx_id);

			rc = cam_sync_signal(req_isp->fence_map_out[j].sync_id,
				CAM_SYNC_STATE_SIGNALED_ERROR);
				CAM_SYNC_STATE_SIGNALED_ERROR,
				CAM_SYNC_ISP_EVENT_BUBBLE);
			if (rc)
				CAM_ERR(CAM_ISP, "Sync failed with rc = %d",
					rc);
@@ -1074,7 +1077,8 @@ static int __cam_isp_ctx_handle_buf_done_for_request_verify_addr(
				ctx->ctx_id);

			rc = cam_sync_signal(req_isp->fence_map_out[j].sync_id,
				CAM_SYNC_STATE_SIGNALED_SUCCESS);
				CAM_SYNC_STATE_SIGNALED_SUCCESS,
				CAM_SYNC_EVENT_SUCCESS);
			if (rc)
				CAM_DBG(CAM_ISP, "Sync failed with rc = %d",
					 rc);
@@ -1087,7 +1091,8 @@ static int __cam_isp_ctx_handle_buf_done_for_request_verify_addr(
				ctx->ctx_id);

			rc = cam_sync_signal(req_isp->fence_map_out[j].sync_id,
				CAM_SYNC_STATE_SIGNALED_ERROR);
				CAM_SYNC_STATE_SIGNALED_ERROR,
				CAM_SYNC_ISP_EVENT_BUBBLE);
			if (rc)
				CAM_ERR(CAM_ISP, "Sync failed with rc = %d",
					rc);
@@ -2003,6 +2008,22 @@ static int __cam_isp_ctx_buf_done_in_bubble_applied(
	return rc;
}

static uint32_t get_evt_param(uint32_t error_type)
{
	switch (error_type) {
	case CAM_ISP_HW_ERROR_OVERFLOW:
		return CAM_SYNC_ISP_EVENT_OVERFLOW;
	case CAM_ISP_HW_ERROR_P2I_ERROR:
		return CAM_SYNC_ISP_EVENT_P2I_ERROR;
	case CAM_ISP_HW_ERROR_VIOLATION:
		return CAM_SYNC_ISP_EVENT_VIOLATION;
	case CAM_ISP_HW_ERROR_BUSIF_OVERFLOW:
		return CAM_SYNC_ISP_EVENT_BUSIF_OVERFLOW;
	default:
		return CAM_SYNC_ISP_EVENT_UNKNOWN;
	}
}

static int __cam_isp_ctx_handle_error(struct cam_isp_context *ctx_isp,
	void *evt_data)
{
@@ -2019,6 +2040,7 @@ static int __cam_isp_ctx_handle_error(struct cam_isp_context *ctx_isp,
	uint64_t                         error_request_id;
	struct cam_hw_fence_map_entry   *fence_map_out = NULL;
	struct cam_req_mgr_message       req_msg;
	uint32_t                         evt_param;

	struct cam_context *ctx = ctx_isp->base;
	struct cam_isp_hw_error_event_data  *error_event_data =
@@ -2043,6 +2065,9 @@ static int __cam_isp_ctx_handle_error(struct cam_isp_context *ctx_isp,
			rc = 0;
		}
	}

	evt_param = get_evt_param(error_type);

	/*
	 * The error is likely caused by first request on the active list.
	 * If active list is empty check wait list (maybe error hit as soon
@@ -2087,7 +2112,8 @@ static int __cam_isp_ctx_handle_error(struct cam_isp_context *ctx_isp,
				if (req_isp->fence_map_out[i].sync_id != -1) {
					rc = cam_sync_signal(
						fence_map_out->sync_id,
						CAM_SYNC_STATE_SIGNALED_ERROR);
						CAM_SYNC_STATE_SIGNALED_ERROR,
						evt_param);
					fence_map_out->sync_id = -1;
				}
			}
@@ -2118,7 +2144,8 @@ static int __cam_isp_ctx_handle_error(struct cam_isp_context *ctx_isp,
				if (req_isp->fence_map_out[i].sync_id != -1) {
					rc = cam_sync_signal(
						fence_map_out->sync_id,
						CAM_SYNC_STATE_SIGNALED_ERROR);
						CAM_SYNC_STATE_SIGNALED_ERROR,
						evt_param);
					fence_map_out->sync_id = -1;
				}
			}
@@ -2181,7 +2208,8 @@ static int __cam_isp_ctx_handle_error(struct cam_isp_context *ctx_isp,
			if (req_isp->fence_map_out[i].sync_id != -1)
				rc = cam_sync_signal(
					req_isp->fence_map_out[i].sync_id,
					CAM_SYNC_STATE_SIGNALED_ERROR);
					CAM_SYNC_STATE_SIGNALED_ERROR,
					evt_param);
			req_isp->fence_map_out[i].sync_id = -1;
		}
		list_del_init(&req->list);
@@ -3139,7 +3167,8 @@ static int __cam_isp_ctx_flush_req(struct cam_context *ctx,
					req_isp->fence_map_out[i].sync_id);
				rc = cam_sync_signal(
					req_isp->fence_map_out[i].sync_id,
					CAM_SYNC_STATE_SIGNALED_CANCEL);
					CAM_SYNC_STATE_SIGNALED_CANCEL,
					CAM_SYNC_ISP_EVENT_FLUSH);
				if (rc) {
					tmp = req_isp->fence_map_out[i].sync_id;
					CAM_ERR_RATE_LIMIT(CAM_ISP,
@@ -3605,7 +3634,8 @@ static int __cam_isp_ctx_rdi_only_sof_in_bubble_state(
			if (req_isp->fence_map_out[i].sync_id != -1) {
				cam_sync_signal(
					req_isp->fence_map_out[i].sync_id,
					CAM_SYNC_STATE_SIGNALED_ERROR);
					CAM_SYNC_STATE_SIGNALED_ERROR,
					CAM_SYNC_ISP_EVENT_BUBBLE);
			}
		list_add_tail(&req->list, &ctx->free_req_list);
		ctx_isp->active_req_cnt--;
@@ -5025,7 +5055,8 @@ static int __cam_isp_ctx_stop_dev_in_activated_unlock(
			if (req_isp->fence_map_out[i].sync_id != -1) {
				cam_sync_signal(
					req_isp->fence_map_out[i].sync_id,
					CAM_SYNC_STATE_SIGNALED_CANCEL);
					CAM_SYNC_STATE_SIGNALED_CANCEL,
					CAM_SYNC_ISP_EVENT_HW_STOP);
			}
		list_add_tail(&req->list, &ctx->free_req_list);
	}
@@ -5041,7 +5072,8 @@ static int __cam_isp_ctx_stop_dev_in_activated_unlock(
			if (req_isp->fence_map_out[i].sync_id != -1) {
				cam_sync_signal(
					req_isp->fence_map_out[i].sync_id,
					CAM_SYNC_STATE_SIGNALED_CANCEL);
					CAM_SYNC_STATE_SIGNALED_CANCEL,
					CAM_SYNC_ISP_EVENT_HW_STOP);
			}
		list_add_tail(&req->list, &ctx->free_req_list);
	}
@@ -5057,7 +5089,8 @@ static int __cam_isp_ctx_stop_dev_in_activated_unlock(
			if (req_isp->fence_map_out[i].sync_id != -1) {
				cam_sync_signal(
					req_isp->fence_map_out[i].sync_id,
					CAM_SYNC_STATE_SIGNALED_CANCEL);
					CAM_SYNC_STATE_SIGNALED_CANCEL,
					CAM_SYNC_ISP_EVENT_HW_STOP);
			}
		list_add_tail(&req->list, &ctx->free_req_list);
	}
+44 −13
Original line number Diff line number Diff line
@@ -184,7 +184,7 @@ int cam_sync_deregister_callback(sync_callback cb_func,
	return found ? 0 : -ENOENT;
}

int cam_sync_signal(int32_t sync_obj, uint32_t status)
int cam_sync_signal(int32_t sync_obj, uint32_t status, uint32_t event_cause)
{
	struct sync_table_row *row = NULL;
	struct sync_table_row *parent_row = NULL;
@@ -228,8 +228,8 @@ int cam_sync_signal(int32_t sync_obj, uint32_t status)
		(status != CAM_SYNC_STATE_SIGNALED_CANCEL)) {
		spin_unlock_bh(&sync_dev->row_spinlocks[sync_obj]);
		CAM_ERR(CAM_SYNC,
			"Error: signaling with undefined status = %d",
			status);
			"Error: signaling with undefined status = %d event reason = %u",
			status, event_cause);
		return -EINVAL;
	}

@@ -239,7 +239,7 @@ int cam_sync_signal(int32_t sync_obj, uint32_t status)
	}

	row->state = status;
	cam_sync_util_dispatch_signaled_cb(sync_obj, status);
	cam_sync_util_dispatch_signaled_cb(sync_obj, status, event_cause);

	/* copy parent list to local and release child lock */
	INIT_LIST_HEAD(&parents_list);
@@ -275,7 +275,8 @@ int cam_sync_signal(int32_t sync_obj, uint32_t status)

		if (!parent_row->remaining)
			cam_sync_util_dispatch_signaled_cb(
				parent_info->sync_id, parent_row->state);
				parent_info->sync_id, parent_row->state,
				event_cause);

		spin_unlock_bh(&sync_dev->row_spinlocks[parent_info->sync_id]);
		list_del_init(&parent_info->list);
@@ -514,7 +515,8 @@ static int cam_sync_handle_signal(struct cam_private_ioctl_arg *k_ioctl)
	}

	return cam_sync_signal(sync_signal.sync_obj,
		sync_signal.sync_state);
		sync_signal.sync_state,
		CAM_SYNC_CAM_SYNC_SIGNAL_EVENT);
}

static int cam_sync_handle_merge(struct cam_private_ioctl_arg *k_ioctl)
@@ -664,7 +666,8 @@ static int cam_sync_handle_register_user_payload(
			sync_obj,
			row->state,
			user_payload_kernel->payload_data,
			CAM_SYNC_USER_PAYLOAD_SIZE * sizeof(__u64));
			CAM_SYNC_USER_PAYLOAD_SIZE * sizeof(__u64),
			CAM_SYNC_REGISTER_PAYLOAD_EVENT);

		spin_unlock_bh(&sync_dev->row_spinlocks[sync_obj]);
		kfree(user_payload_kernel);
@@ -869,7 +872,8 @@ static int cam_sync_close(struct file *filep)
			 */
			if (row->state == CAM_SYNC_STATE_ACTIVE) {
				rc = cam_sync_signal(i,
					CAM_SYNC_STATE_SIGNALED_ERROR);
					CAM_SYNC_STATE_SIGNALED_ERROR,
					CAM_SYNC_v4l2_RELEASE_EVENT);
				if (rc < 0)
					CAM_ERR(CAM_SYNC,
					  "Cleanup signal fail idx:%d\n",
@@ -912,12 +916,25 @@ static int cam_sync_close(struct file *filep)
static void cam_sync_event_queue_notify_error(const struct v4l2_event *old,
	struct v4l2_event *new)
{
	if (sync_dev->version == CAM_SYNC_V4L_EVENT_V2) {
		struct cam_sync_ev_header_v2 *ev_header;

		ev_header = CAM_SYNC_GET_HEADER_PTR_V2((*old));
		CAM_ERR(CAM_CRM,
			"Failed to notify event id %d fence %d statue %d reason %u %u %u %u",
			old->id, ev_header->sync_obj, ev_header->status,
			ev_header->evt_param[0], ev_header->evt_param[1],
			ev_header->evt_param[2], ev_header->evt_param[3]);

	} else {
		struct cam_sync_ev_header *ev_header;

		ev_header = CAM_SYNC_GET_HEADER_PTR((*old));
	CAM_ERR(CAM_CRM, "Failed to notify event id %d fence %d statue %d",
		CAM_ERR(CAM_CRM,
			"Failed to notify event id %d fence %d statue %d",
			old->id, ev_header->sync_obj, ev_header->status);
	}
}

static struct v4l2_subscribed_event_ops cam_sync_v4l2_ops = {
	.merge = cam_sync_event_queue_notify_error,
@@ -926,6 +943,14 @@ static struct v4l2_subscribed_event_ops cam_sync_v4l2_ops = {
int cam_sync_subscribe_event(struct v4l2_fh *fh,
		const struct v4l2_event_subscription *sub)
{
	if (!((sub->type == CAM_SYNC_V4L_EVENT) ||
	(sub->type == CAM_SYNC_V4L_EVENT_V2))) {
		CAM_ERR(CAM_SYNC, "Non supported event type 0x%x", sub->type);
		return -EINVAL;
	}

	sync_dev->version = sub->type;
	CAM_DBG(CAM_SYNC, "Sync event verion type 0x%x", sync_dev->version);
	return v4l2_event_subscribe(fh, sub, CAM_SYNC_MAX_V4L2_EVENTS,
		&cam_sync_v4l2_ops);
}
@@ -933,6 +958,12 @@ int cam_sync_subscribe_event(struct v4l2_fh *fh,
int cam_sync_unsubscribe_event(struct v4l2_fh *fh,
		const struct v4l2_event_subscription *sub)
{
	if (!((sub->type == CAM_SYNC_V4L_EVENT) ||
	(sub->type == CAM_SYNC_V4L_EVENT_V2))) {
		CAM_ERR(CAM_SYNC, "Non supported event type 0x%x", sub->type);
		return -EINVAL;
	}

	return v4l2_event_unsubscribe(fh, sub);
}

@@ -1068,7 +1099,7 @@ int cam_synx_sync_signal(int32_t sync_obj, uint32_t synx_status)
		break;
	}

	rc = cam_sync_signal(sync_obj, sync_status);
	rc = cam_sync_signal(sync_obj, sync_status, CAM_SYNC_EVENT_SYNX);
	if (rc) {
		CAM_ERR(CAM_SYNC,
			"synx signal failed with %d, sync_obj=%d, synx_status=%d, sync_status=%d",
Loading