Merge "msm: camera: sync: Add SYNC_V4L_EVENT_V2 support in sync driver" into camera-kernel.lnx.4.0

This commit is contained in:
Camera Software Integration
2020-08-20 15:02:51 -07:00
committed by Gerrit - the friendly Code Review server
10 changed files with 251 additions and 53 deletions

View File

@@ -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++) { for (j = 0; j < req->num_out_map_entries; j++) {
CAM_DBG(CAM_REQ, "fence %d signal with %d", CAM_DBG(CAM_REQ, "fence %d signal with %d",
req->out_map_entries[j].sync_id, result); 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; 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) { if (req->out_map_entries[i].sync_id != -1) {
rc = cam_sync_signal( rc = cam_sync_signal(
req->out_map_entries[i].sync_id, req->out_map_entries[i].sync_id,
CAM_SYNC_STATE_SIGNALED_CANCEL); CAM_SYNC_STATE_SIGNALED_CANCEL,
CAM_SYNC_EVENT_FLUSH);
if (rc == -EALREADY) { if (rc == -EALREADY) {
CAM_ERR(CAM_CTXT, CAM_ERR(CAM_CTXT,
"Req: %llu already signalled, sync_id:%d", "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) { if (req->out_map_entries[i].sync_id != -1) {
rc = cam_sync_signal( rc = cam_sync_signal(
req->out_map_entries[i].sync_id, req->out_map_entries[i].sync_id,
CAM_SYNC_STATE_SIGNALED_CANCEL); CAM_SYNC_STATE_SIGNALED_CANCEL,
CAM_SYNC_EVENT_FLUSH);
if (rc == -EALREADY) { if (rc == -EALREADY) {
CAM_ERR(CAM_CTXT, CAM_ERR(CAM_CTXT,
"Req: %llu already signalled ctx: %pK dev_name: %s dev_handle: %d ctx_state: %d", "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; req->out_map_entries[i].sync_id;
if (sync_id != -1) { if (sync_id != -1) {
rc = cam_sync_signal(sync_id, rc = cam_sync_signal(sync_id,
CAM_SYNC_STATE_SIGNALED_CANCEL); CAM_SYNC_STATE_SIGNALED_CANCEL,
CAM_SYNC_EVENT_FLUSH);
if (rc == -EALREADY) { if (rc == -EALREADY) {
CAM_ERR(CAM_CTXT, CAM_ERR(CAM_CTXT,
"Req: %llu already signalled, sync_id:%d", "Req: %llu already signalled, sync_id:%d",

View File

@@ -90,6 +90,7 @@ struct cam_hw_fence_map_entry {
* @resrouce_handle: list of the resource handle * @resrouce_handle: list of the resource handle
* @timestamp: time stamp * @timestamp: time stamp
* @request_id: request identifier * @request_id: request identifier
* @evt_param: event parameter
* *
*/ */
struct cam_hw_done_event_data { 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]; uint32_t resource_handle[CAM_NUM_OUT_PER_COMP_IRQ_MAX];
struct timeval timestamp; struct timeval timestamp;
uint64_t request_id; uint64_t request_id;
uint32_t evt_param;
}; };
/** /**

View File

@@ -182,7 +182,8 @@ static int __cam_custom_ctx_frame_done(
} }
rc = cam_sync_signal(req_custom->fence_map_out[j].sync_id, 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) if (rc)
CAM_ERR(CAM_CUSTOM, "Sync failed with rc = %d", 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); req_custom->fence_map_out[i].sync_id);
rc = cam_sync_signal( rc = cam_sync_signal(
req_custom->fence_map_out[i].sync_id, req_custom->fence_map_out[i].sync_id,
CAM_SYNC_STATE_SIGNALED_CANCEL); CAM_SYNC_STATE_SIGNALED_CANCEL,
CAM_SYNC_EVENT_FLUSH);
if (rc) if (rc)
CAM_ERR_RATE_LIMIT(CAM_CUSTOM, CAM_ERR_RATE_LIMIT(CAM_CUSTOM,
"signal fence failed\n"); "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) { if (req_custom->fence_map_out[i].sync_id != -1) {
cam_sync_signal( cam_sync_signal(
req_custom->fence_map_out[i].sync_id, 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); 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) { if (req_custom->fence_map_out[i].sync_id != -1) {
cam_sync_signal( cam_sync_signal(
req_custom->fence_map_out[i].sync_id, 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); 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) { if (req_custom->fence_map_out[i].sync_id != -1) {
cam_sync_signal( cam_sync_signal(
req_custom->fence_map_out[i].sync_id, 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); list_add_tail(&req->list, &ctx->free_req_list);
} }

View File

@@ -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++) for (i = 0; i < req_isp->num_fence_map_out; i++)
rc = cam_sync_signal( rc = cam_sync_signal(
req_isp->fence_map_out[i].sync_id, 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); list_add_tail(&req->list, &ctx->free_req_list);
CAM_DBG(CAM_REQ, CAM_DBG(CAM_REQ,
@@ -935,7 +936,8 @@ static int __cam_isp_ctx_handle_buf_done_for_request(
ctx->ctx_id); ctx->ctx_id);
rc = cam_sync_signal(req_isp->fence_map_out[j].sync_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) if (rc)
CAM_DBG(CAM_ISP, "Sync failed with rc = %d", CAM_DBG(CAM_ISP, "Sync failed with rc = %d",
rc); rc);
@@ -948,7 +950,8 @@ static int __cam_isp_ctx_handle_buf_done_for_request(
ctx->ctx_id); ctx->ctx_id);
rc = cam_sync_signal(req_isp->fence_map_out[j].sync_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) if (rc)
CAM_ERR(CAM_ISP, "Sync failed with rc = %d", CAM_ERR(CAM_ISP, "Sync failed with rc = %d",
rc); rc);
@@ -1074,7 +1077,8 @@ static int __cam_isp_ctx_handle_buf_done_for_request_verify_addr(
ctx->ctx_id); ctx->ctx_id);
rc = cam_sync_signal(req_isp->fence_map_out[j].sync_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) if (rc)
CAM_DBG(CAM_ISP, "Sync failed with rc = %d", CAM_DBG(CAM_ISP, "Sync failed with rc = %d",
rc); rc);
@@ -1087,7 +1091,8 @@ static int __cam_isp_ctx_handle_buf_done_for_request_verify_addr(
ctx->ctx_id); ctx->ctx_id);
rc = cam_sync_signal(req_isp->fence_map_out[j].sync_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) if (rc)
CAM_ERR(CAM_ISP, "Sync failed with rc = %d", CAM_ERR(CAM_ISP, "Sync failed with rc = %d",
rc); rc);
@@ -2003,6 +2008,22 @@ static int __cam_isp_ctx_buf_done_in_bubble_applied(
return rc; 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, static int __cam_isp_ctx_handle_error(struct cam_isp_context *ctx_isp,
void *evt_data) 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; uint64_t error_request_id;
struct cam_hw_fence_map_entry *fence_map_out = NULL; struct cam_hw_fence_map_entry *fence_map_out = NULL;
struct cam_req_mgr_message req_msg; struct cam_req_mgr_message req_msg;
uint32_t evt_param;
struct cam_context *ctx = ctx_isp->base; struct cam_context *ctx = ctx_isp->base;
struct cam_isp_hw_error_event_data *error_event_data = 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; rc = 0;
} }
} }
evt_param = get_evt_param(error_type);
/* /*
* The error is likely caused by first request on the active list. * 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 * 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) { if (req_isp->fence_map_out[i].sync_id != -1) {
rc = cam_sync_signal( rc = cam_sync_signal(
fence_map_out->sync_id, fence_map_out->sync_id,
CAM_SYNC_STATE_SIGNALED_ERROR); CAM_SYNC_STATE_SIGNALED_ERROR,
evt_param);
fence_map_out->sync_id = -1; 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) { if (req_isp->fence_map_out[i].sync_id != -1) {
rc = cam_sync_signal( rc = cam_sync_signal(
fence_map_out->sync_id, fence_map_out->sync_id,
CAM_SYNC_STATE_SIGNALED_ERROR); CAM_SYNC_STATE_SIGNALED_ERROR,
evt_param);
fence_map_out->sync_id = -1; fence_map_out->sync_id = -1;
} }
} }
@@ -2181,7 +2208,8 @@ end:
if (req_isp->fence_map_out[i].sync_id != -1) if (req_isp->fence_map_out[i].sync_id != -1)
rc = cam_sync_signal( rc = cam_sync_signal(
req_isp->fence_map_out[i].sync_id, 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; req_isp->fence_map_out[i].sync_id = -1;
} }
list_del_init(&req->list); 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); req_isp->fence_map_out[i].sync_id);
rc = cam_sync_signal( rc = cam_sync_signal(
req_isp->fence_map_out[i].sync_id, 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) { if (rc) {
tmp = req_isp->fence_map_out[i].sync_id; tmp = req_isp->fence_map_out[i].sync_id;
CAM_ERR_RATE_LIMIT(CAM_ISP, 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) { if (req_isp->fence_map_out[i].sync_id != -1) {
cam_sync_signal( cam_sync_signal(
req_isp->fence_map_out[i].sync_id, 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); list_add_tail(&req->list, &ctx->free_req_list);
ctx_isp->active_req_cnt--; 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) { if (req_isp->fence_map_out[i].sync_id != -1) {
cam_sync_signal( cam_sync_signal(
req_isp->fence_map_out[i].sync_id, 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); 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) { if (req_isp->fence_map_out[i].sync_id != -1) {
cam_sync_signal( cam_sync_signal(
req_isp->fence_map_out[i].sync_id, 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); 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) { if (req_isp->fence_map_out[i].sync_id != -1) {
cam_sync_signal( cam_sync_signal(
req_isp->fence_map_out[i].sync_id, 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); list_add_tail(&req->list, &ctx->free_req_list);
} }

View File

@@ -184,7 +184,7 @@ int cam_sync_deregister_callback(sync_callback cb_func,
return found ? 0 : -ENOENT; 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 *row = NULL;
struct sync_table_row *parent_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)) { (status != CAM_SYNC_STATE_SIGNALED_CANCEL)) {
spin_unlock_bh(&sync_dev->row_spinlocks[sync_obj]); spin_unlock_bh(&sync_dev->row_spinlocks[sync_obj]);
CAM_ERR(CAM_SYNC, CAM_ERR(CAM_SYNC,
"Error: signaling with undefined status = %d", "Error: signaling with undefined status = %d event reason = %u",
status); status, event_cause);
return -EINVAL; return -EINVAL;
} }
@@ -239,7 +239,7 @@ int cam_sync_signal(int32_t sync_obj, uint32_t status)
} }
row->state = 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 */ /* copy parent list to local and release child lock */
INIT_LIST_HEAD(&parents_list); INIT_LIST_HEAD(&parents_list);
@@ -275,7 +275,8 @@ int cam_sync_signal(int32_t sync_obj, uint32_t status)
if (!parent_row->remaining) if (!parent_row->remaining)
cam_sync_util_dispatch_signaled_cb( 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]); spin_unlock_bh(&sync_dev->row_spinlocks[parent_info->sync_id]);
list_del_init(&parent_info->list); 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, 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) 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, sync_obj,
row->state, row->state,
user_payload_kernel->payload_data, 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]); spin_unlock_bh(&sync_dev->row_spinlocks[sync_obj]);
kfree(user_payload_kernel); kfree(user_payload_kernel);
@@ -869,7 +872,8 @@ static int cam_sync_close(struct file *filep)
*/ */
if (row->state == CAM_SYNC_STATE_ACTIVE) { if (row->state == CAM_SYNC_STATE_ACTIVE) {
rc = cam_sync_signal(i, rc = cam_sync_signal(i,
CAM_SYNC_STATE_SIGNALED_ERROR); CAM_SYNC_STATE_SIGNALED_ERROR,
CAM_SYNC_v4l2_RELEASE_EVENT);
if (rc < 0) if (rc < 0)
CAM_ERR(CAM_SYNC, CAM_ERR(CAM_SYNC,
"Cleanup signal fail idx:%d\n", "Cleanup signal fail idx:%d\n",
@@ -912,11 +916,24 @@ static int cam_sync_close(struct file *filep)
static void cam_sync_event_queue_notify_error(const struct v4l2_event *old, static void cam_sync_event_queue_notify_error(const struct v4l2_event *old,
struct v4l2_event *new) struct v4l2_event *new)
{ {
struct cam_sync_ev_header *ev_header; if (sync_dev->version == CAM_SYNC_V4L_EVENT_V2) {
struct cam_sync_ev_header_v2 *ev_header;
ev_header = CAM_SYNC_GET_HEADER_PTR((*old)); ev_header = CAM_SYNC_GET_HEADER_PTR_V2((*old));
CAM_ERR(CAM_CRM, "Failed to notify event id %d fence %d statue %d", CAM_ERR(CAM_CRM,
old->id, ev_header->sync_obj, ev_header->status); "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",
old->id, ev_header->sync_obj, ev_header->status);
}
} }
static struct v4l2_subscribed_event_ops cam_sync_v4l2_ops = { static struct v4l2_subscribed_event_ops cam_sync_v4l2_ops = {
@@ -926,6 +943,14 @@ static struct v4l2_subscribed_event_ops cam_sync_v4l2_ops = {
int cam_sync_subscribe_event(struct v4l2_fh *fh, int cam_sync_subscribe_event(struct v4l2_fh *fh,
const struct v4l2_event_subscription *sub) 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, return v4l2_event_subscribe(fh, sub, CAM_SYNC_MAX_V4L2_EVENTS,
&cam_sync_v4l2_ops); &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, int cam_sync_unsubscribe_event(struct v4l2_fh *fh,
const struct v4l2_event_subscription *sub) 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); return v4l2_event_unsubscribe(fh, sub);
} }
@@ -1068,7 +1099,7 @@ int cam_synx_sync_signal(int32_t sync_obj, uint32_t synx_status)
break; break;
} }
rc = cam_sync_signal(sync_obj, sync_status); rc = cam_sync_signal(sync_obj, sync_status, CAM_SYNC_EVENT_SYNX);
if (rc) { if (rc) {
CAM_ERR(CAM_SYNC, CAM_ERR(CAM_SYNC,
"synx signal failed with %d, sync_obj=%d, synx_status=%d, sync_status=%d", "synx signal failed with %d, sync_obj=%d, synx_status=%d, sync_status=%d",

View File

@@ -76,10 +76,11 @@ int cam_sync_deregister_callback(sync_callback cb_func,
* @param sync_obj: int referencing the sync object. * @param sync_obj: int referencing the sync object.
* @param status: Status of the signaling. Can be either SYNC_SIGNAL_ERROR or * @param status: Status of the signaling. Can be either SYNC_SIGNAL_ERROR or
* SYNC_SIGNAL_SUCCESS. * SYNC_SIGNAL_SUCCESS.
* @param evt_param: Event parameter
* *
* @return Status of operation. Negative in case of error. Zero otherwise. * @return Status of operation. Negative in case of error. Zero otherwise.
*/ */
int cam_sync_signal(int32_t sync_obj, uint32_t status); int cam_sync_signal(int32_t sync_obj, uint32_t status, uint32_t evt_param);
/** /**
* @brief: Merges multiple sync objects * @brief: Merges multiple sync objects

View File

@@ -182,6 +182,7 @@ struct cam_signalable_info {
* @cam_sync_eventq : Event queue used to dispatch user payloads to user space * @cam_sync_eventq : Event queue used to dispatch user payloads to user space
* @bitmap : Bitmap representation of all sync objects * @bitmap : Bitmap representation of all sync objects
* @params : Parameters for synx call back registration * @params : Parameters for synx call back registration
* @version : version support
*/ */
struct sync_device { struct sync_device {
struct video_device *vdev; struct video_device *vdev;
@@ -198,6 +199,7 @@ struct sync_device {
#if IS_REACHABLE(CONFIG_MSM_GLOBAL_SYNX) #if IS_REACHABLE(CONFIG_MSM_GLOBAL_SYNX)
struct synx_register_params params; struct synx_register_params params;
#endif #endif
uint32_t version;
}; };

View File

@@ -300,7 +300,7 @@ void cam_sync_util_cb_dispatch(struct work_struct *cb_dispatch_work)
} }
void cam_sync_util_dispatch_signaled_cb(int32_t sync_obj, void cam_sync_util_dispatch_signaled_cb(int32_t sync_obj,
uint32_t status) uint32_t status, uint32_t event_cause)
{ {
struct sync_callback_info *sync_cb; struct sync_callback_info *sync_cb;
struct sync_user_payload *payload_info; struct sync_user_payload *payload_info;
@@ -339,7 +339,8 @@ void cam_sync_util_dispatch_signaled_cb(int32_t sync_obj,
sync_obj, sync_obj,
status, status,
payload_info->payload_data, payload_info->payload_data,
CAM_SYNC_PAYLOAD_WORDS * sizeof(__u64)); CAM_SYNC_PAYLOAD_WORDS * sizeof(__u64),
event_cause);
list_del_init(&payload_info->list); list_del_init(&payload_info->list);
/* /*
@@ -361,24 +362,40 @@ void cam_sync_util_send_v4l2_event(uint32_t id,
uint32_t sync_obj, uint32_t sync_obj,
int status, int status,
void *payload, void *payload,
int len) int len, uint32_t event_cause)
{ {
struct v4l2_event event; struct v4l2_event event;
__u64 *payload_data = NULL; __u64 *payload_data = NULL;
struct cam_sync_ev_header *ev_header = NULL;
event.id = id; if (sync_dev->version == CAM_SYNC_V4L_EVENT_V2) {
event.type = CAM_SYNC_V4L_EVENT; struct cam_sync_ev_header_v2 *ev_header = NULL;
ev_header = CAM_SYNC_GET_HEADER_PTR(event); event.id = id;
ev_header->sync_obj = sync_obj; event.type = CAM_SYNC_V4L_EVENT_V2;
ev_header->status = status;
ev_header = CAM_SYNC_GET_HEADER_PTR_V2(event);
ev_header->sync_obj = sync_obj;
ev_header->status = status;
ev_header->version = sync_dev->version;
ev_header->evt_param[CAM_SYNC_EVENT_REASON_CODE_INDEX] =
event_cause;
payload_data = CAM_SYNC_GET_PAYLOAD_PTR_V2(event, __u64);
} else {
struct cam_sync_ev_header *ev_header = NULL;
event.id = id;
event.type = CAM_SYNC_V4L_EVENT;
ev_header = CAM_SYNC_GET_HEADER_PTR(event);
ev_header->sync_obj = sync_obj;
ev_header->status = status;
payload_data = CAM_SYNC_GET_PAYLOAD_PTR(event, __u64);
}
payload_data = CAM_SYNC_GET_PAYLOAD_PTR(event, __u64);
memcpy(payload_data, payload, len); memcpy(payload_data, payload, len);
v4l2_event_queue(sync_dev->vdev, &event); v4l2_event_queue(sync_dev->vdev, &event);
CAM_DBG(CAM_SYNC, "send v4l2 event for sync_obj :%d", CAM_DBG(CAM_SYNC, "send v4l2 event version %d for sync_obj :%d",
sync_dev->version,
sync_obj); sync_obj);
} }

View File

@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */ /* SPDX-License-Identifier: GPL-2.0-only */
/* /*
* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
*/ */
#ifndef __CAM_SYNC_UTIL_H__ #ifndef __CAM_SYNC_UTIL_H__
@@ -82,13 +82,14 @@ void cam_sync_util_cb_dispatch(struct work_struct *cb_dispatch_work);
/** /**
* @brief: Function to dispatch callbacks for a signaled sync object * @brief: Function to dispatch callbacks for a signaled sync object
* *
* @sync_obj : Sync object that is signaled * @sync_obj : Sync object that is signaled
* @status : Status of the signaled object * @status : Status of the signaled object
* @evt_param : Event paramaeter
* *
* @return None * @return None
*/ */
void cam_sync_util_dispatch_signaled_cb(int32_t sync_obj, void cam_sync_util_dispatch_signaled_cb(int32_t sync_obj,
uint32_t status); uint32_t status, uint32_t evt_param);
/** /**
* @brief: Function to send V4L event to user space * @brief: Function to send V4L event to user space
@@ -97,6 +98,7 @@ void cam_sync_util_dispatch_signaled_cb(int32_t sync_obj,
* @param status : Status of the event * @param status : Status of the event
* @payload : Payload that needs to be sent to user space * @payload : Payload that needs to be sent to user space
* @len : Length of the payload * @len : Length of the payload
* @evt_param : Event Paramenter
* *
* @return None * @return None
*/ */
@@ -104,7 +106,8 @@ void cam_sync_util_send_v4l2_event(uint32_t id,
uint32_t sync_obj, uint32_t sync_obj,
int status, int status,
void *payload, void *payload,
int len); int len,
uint32_t evt_param);
/** /**
* @brief: Function which gets the next state of the sync object based on the * @brief: Function which gets the next state of the sync object based on the

View File

@@ -15,6 +15,7 @@
/* V4L event which user space will subscribe to */ /* V4L event which user space will subscribe to */
#define CAM_SYNC_V4L_EVENT (V4L2_EVENT_PRIVATE_START + 0) #define CAM_SYNC_V4L_EVENT (V4L2_EVENT_PRIVATE_START + 0)
#define CAM_SYNC_V4L_EVENT_V2 (V4L2_EVENT_PRIVATE_START + 1)
/* Specific event ids to get notified in user space */ /* Specific event ids to get notified in user space */
#define CAM_SYNC_V4L_EVENT_ID_CB_TRIG 0 #define CAM_SYNC_V4L_EVENT_ID_CB_TRIG 0
@@ -31,12 +32,96 @@
#define CAM_SYNC_GET_HEADER_PTR(ev) \ #define CAM_SYNC_GET_HEADER_PTR(ev) \
((struct cam_sync_ev_header *)ev.u.data) ((struct cam_sync_ev_header *)ev.u.data)
#define CAM_SYNC_GET_PAYLOAD_PTR_V2(ev, type) \
(type *)((char *)ev.u.data + sizeof(struct cam_sync_ev_header_v2))
#define CAM_SYNC_GET_HEADER_PTR_V2(ev) \
((struct cam_sync_ev_header_v2 *)ev.u.data)
#define CAM_SYNC_STATE_INVALID 0 #define CAM_SYNC_STATE_INVALID 0
#define CAM_SYNC_STATE_ACTIVE 1 #define CAM_SYNC_STATE_ACTIVE 1
#define CAM_SYNC_STATE_SIGNALED_SUCCESS 2 #define CAM_SYNC_STATE_SIGNALED_SUCCESS 2
#define CAM_SYNC_STATE_SIGNALED_ERROR 3 #define CAM_SYNC_STATE_SIGNALED_ERROR 3
#define CAM_SYNC_STATE_SIGNALED_CANCEL 4 #define CAM_SYNC_STATE_SIGNALED_CANCEL 4
/* Top level sync event reason types */
#define CAM_SYNC_EVENT_UNKNOWN 0
#define CAM_SYNC_EVENT_SUCCESS 1
#define CAM_SYNC_EVENT_FLUSH 2
#define CAM_SYNC_EVENT_STOP 3
#define CAM_SYNC_EVENT_SYNX 4
/* ISP Sync event reason types */
#define CAM_SYNC_ISP_EVENT_START 20
#define CAM_SYNC_ISP_EVENT_UNKNOWN (CAM_SYNC_ISP_EVENT_START + 0)
#define CAM_SYNC_ISP_EVENT_BUBBLE (CAM_SYNC_ISP_EVENT_START + 1)
#define CAM_SYNC_ISP_EVENT_OVERFLOW (CAM_SYNC_ISP_EVENT_START + 2)
#define CAM_SYNC_ISP_EVENT_P2I_ERROR (CAM_SYNC_ISP_EVENT_START + 3)
#define CAM_SYNC_ISP_EVENT_VIOLATION (CAM_SYNC_ISP_EVENT_START + 4)
#define CAM_SYNC_ISP_EVENT_BUSIF_OVERFLOW (CAM_SYNC_ISP_EVENT_START + 5)
#define CAM_SYNC_ISP_EVENT_FLUSH (CAM_SYNC_ISP_EVENT_START + 6)
#define CAM_SYNC_ISP_EVENT_HW_STOP (CAM_SYNC_ISP_EVENT_START + 7)
#define CAM_SYNC_ISP_EVENT_END (CAM_SYNC_ISP_EVENT_START + 50)
/* ICP Sync event reason types */
#define CAM_SYNC_ICP_EVENT_START (CAM_SYNC_ISP_EVENT_END + 1)
#define CAM_SYNC_ICP_EVENT_UNKNOWN (CAM_SYNC_ICP_EVENT_START + 0)
#define CAM_SYNC_ICP_EVENT_FRAME_PROCESS_FAILURE (CAM_SYNC_ICP_EVENT_START + 1)
#define CAM_SYNC_ICP_EVENT_CONFIG_ERR (CAM_SYNC_ICP_EVENT_START + 2)
#define CAM_SYNC_ICP_EVENT_END (CAM_SYNC_ICP_EVENT_START + 50)
/* JPEG Sync event reason types */
#define CAM_SYNC_JPEG_EVENT_START (CAM_SYNC_ICP_EVENT_END + 1)
#define CAM_SYNC_JPEG_EVENT_UNKNOWN (CAM_SYNC_JPEG_EVENT_START + 0)
#define CAM_SYNC_JPEG_EVENT_INVLD_CMD (CAM_SYNC_JPEG_EVENT_START + 1)
#define CAM_SYNC_JPEG_EVENT_SET_IRQ_CB (CAM_SYNC_JPEG_EVENT_START + 2)
#define CAM_SYNC_JPEG_EVENT_HW_RESET_FAILED (CAM_SYNC_JPEG_EVENT_START + 3)
#define CAM_SYNC_JPEG_EVENT_CDM_CHANGE_BASE_ERR (CAM_SYNC_JPEG_EVENT_START + 4)
#define CAM_SYNC_JPEG_EVENT_CDM_CONFIG_ERR (CAM_SYNC_JPEG_EVENT_START + 5)
#define CAM_SYNC_JPEG_EVENT_START_HW_ERR (CAM_SYNC_JPEG_EVENT_START + 6)
#define CAM_SYNC_JPEG_EVENT_END (CAM_SYNC_JPEG_EVENT_START + 50)
/* FD Sync event reason types */
#define CAM_SYNC_FD_EVENT_START (CAM_SYNC_JPEG_EVENT_END + 1)
#define CAM_SYNC_FD_EVENT_UNKNOWN (CAM_SYNC_FD_EVENT_START + 0)
#define CAM_SYNC_FD_EVENT_IRQ_FRAME_DONE (CAM_SYNC_FD_EVENT_START + 1)
#define CAM_SYNC_FD_EVENT_IRQ_RESET_DONE (CAM_SYNC_FD_EVENT_START + 2)
#define CAM_SYNC_FD_EVENT_HALT (CAM_SYNC_FD_EVENT_START + 3)
#define CAM_SYNC_FD_EVENT_END (CAM_SYNC_FD_EVENT_START + 50)
/* LRME Sync event reason types */
#define CAM_SYNC_LRME_EVENT_START (CAM_SYNC_FD_EVENT_END + 1)
#define CAM_SYNC_LRME_EVENT_UNKNOWN (CAM_SYNC_LRME_EVENT_START + 0)
#define CAM_SYNC_LRME_EVENT_CB_ERROR (CAM_SYNC_LRME_EVENT_START + 1)
#define CAM_SYNC_LRME_EVENT_END (CAM_SYNC_LRME_EVENT_START + 50)
/* OPE Sync event reason types */
#define CAM_SYNC_OPE_EVENT_START (CAM_SYNC_LRME_EVENT_END + 1)
#define CAM_SYNC_OPE_EVENT_UNKNOWN (CAM_SYNC_OPE_EVENT_START + 0)
#define CAM_SYNC_OPE_EVENT_PAGE_FAULT (CAM_SYNC_OPE_EVENT_START + 1)
#define CAM_SYNC_OPE_EVENT_HW_HANG (CAM_SYNC_OPE_EVENT_START + 2)
#define CAM_SYNC_OPE_EVENT_HALT (CAM_SYNC_OPE_EVENT_START + 3)
#define CAM_SYNC_OPE_EVENT_CONFIG_ERR (CAM_SYNC_OPE_EVENT_START + 4)
#define CAM_SYNC_OPE_EVENT_HW_FLUSH (CAM_SYNC_OPE_EVENT_START + 5)
#define CAM_SYNC_OPE_EVENT_HW_RESUBMIT (CAM_SYNC_OPE_EVENT_START + 6)
#define CAM_SYNC_OPE_EVENT_HW_RESET_DONE (CAM_SYNC_OPE_EVENT_START + 7)
#define CAM_SYNC_OPE_EVENT_HW_ERROR (CAM_SYNC_OPE_EVENT_START + 8)
#define CAM_SYNC_OPE_EVENT_INVLD_CMD (CAM_SYNC_OPE_EVENT_START + 9)
#define CAM_SYNC_OPE_EVENT_HW_RESET_FAILED (CAM_SYNC_OPE_EVENT_START + 10)
#define CAM_SYNC_OPE_EVENT_END (CAM_SYNC_OPE_EVENT_START + 50)
/* Others ioctl/v4l2 Sync event reason types */
#define CAM_SYNC_OTHER_EVENT_START (CAM_SYNC_OPE_EVENT_END + 1)
#define CAM_SYNC_REGISTER_PAYLOAD_EVENT (CAM_SYNC_OTHER_EVENT_START + 0)
#define CAM_SYNC_CAM_SYNC_SIGNAL_EVENT (CAM_SYNC_OTHER_EVENT_START + 1)
#define CAM_SYNC_v4l2_RELEASE_EVENT (CAM_SYNC_OTHER_EVENT_START + 2)
#define CAM_SYNC_OTHER_EVENT_END (CAM_SYNC_OTHER_EVENT_START + 50)
#define CAM_SYNC_EVENT_CNT 7
#define CAM_SYNC_EVENT_REASON_CODE_INDEX 0
/** /**
* struct cam_sync_ev_header - Event header for sync event notification * struct cam_sync_ev_header - Event header for sync event notification
* *
@@ -48,6 +133,21 @@ struct cam_sync_ev_header {
__s32 status; __s32 status;
}; };
/**
* struct cam_sync_ev_header_v2 - Event header for sync event notification
*
* @sync_obj: Sync object
* @status: Status of the object
* @version: sync driver version
* @evt_param: event parameter
*/
struct cam_sync_ev_header_v2 {
__s32 sync_obj;
__s32 status;
uint32_t version;
uint32_t evt_param[CAM_SYNC_EVENT_CNT];
};
/** /**
* struct cam_sync_info - Sync object creation information * struct cam_sync_info - Sync object creation information
* *