From 6b38f7e1bf78b68bb47a472c08ae944409abd2a6 Mon Sep 17 00:00:00 2001 From: Depeng Shao Date: Thu, 19 Sep 2019 14:44:53 +0800 Subject: [PATCH] msm: camera: reqmgr: Verify the req of two links The req of two links should be same if current frame sync with previous frame of sync link, CRM can do self-correction based on this condition. CRs-Fixed: 2492019 Change-Id: Idb208958a850ec1fe12f12443e7ecc2e126970d8 Signed-off-by: Depeng Shao --- drivers/cam_req_mgr/cam_req_mgr_core.c | 53 ++++++++++++++++++++++++-- 1 file changed, 49 insertions(+), 4 deletions(-) diff --git a/drivers/cam_req_mgr/cam_req_mgr_core.c b/drivers/cam_req_mgr/cam_req_mgr_core.c index 4b872824041f..97e1dce27f8d 100644 --- a/drivers/cam_req_mgr/cam_req_mgr_core.c +++ b/drivers/cam_req_mgr/cam_req_mgr_core.c @@ -995,7 +995,8 @@ static int __cam_req_mgr_check_sync_req_is_ready( struct cam_req_mgr_slot *slot) { struct cam_req_mgr_core_link *sync_link = NULL; - int64_t req_id = 0; + struct cam_req_mgr_slot *sync_rd_slot = NULL; + int64_t req_id = 0, sync_req_id = 0; int sync_slot_idx = 0, sync_rd_idx = 0, rc = 0; int32_t sync_num_slots = 0; uint64_t sync_frame_duration = 0; @@ -1009,6 +1010,9 @@ static int __cam_req_mgr_check_sync_req_is_ready( sync_link = link->sync_link; req_id = slot->req_id; sync_num_slots = sync_link->req.in_q->num_slots; + sync_rd_idx = sync_link->req.in_q->rd_idx; + sync_rd_slot = &sync_link->req.in_q->slot[sync_rd_idx]; + sync_req_id = sync_rd_slot->req_id; CAM_DBG(CAM_REQ, "link_hdl %x req %lld frame_skip_flag %d ", @@ -1091,12 +1095,11 @@ static int __cam_req_mgr_check_sync_req_is_ready( return -EAGAIN; } - sync_rd_idx = sync_link->req.in_q->rd_idx; if ((sync_link->req.in_q->slot[sync_slot_idx].status != CRM_SLOT_STATUS_REQ_APPLIED) && (((sync_slot_idx - sync_rd_idx + sync_num_slots) % sync_num_slots) >= 1) && - (sync_link->req.in_q->slot[sync_rd_idx].status != + (sync_rd_slot->status != CRM_SLOT_STATUS_REQ_APPLIED)) { CAM_DBG(CAM_CRM, "Req: %lld [other link] not next req to be applied on link: %x", @@ -1129,7 +1132,14 @@ static int __cam_req_mgr_check_sync_req_is_ready( CAM_DBG(CAM_CRM, "Req: %lld ready %d sync_ready %d, ignore sync link next SOF", req_id, ready, sync_ready); - link->sync_link_sof_skip = true; + + /* + * Only skip the frames if current frame sync with + * next frame of sync link. + */ + if (link->sof_timestamp - sync_link->sof_timestamp > + sync_frame_duration / 2) + link->sync_link_sof_skip = true; return -EINVAL; } else if (ready == false) { CAM_DBG(CAM_CRM, @@ -1138,6 +1148,41 @@ static int __cam_req_mgr_check_sync_req_is_ready( return -EINVAL; } + /* + * Do the self-correction when the frames are sync, + * we consider that the frames are synced if the + * difference of two SOF timestamp less than + * (sync_frame_duration / 5). + */ + if ((link->sof_timestamp > sync_link->sof_timestamp) && + (sync_link->sof_timestamp > 0) && + (link->sof_timestamp - sync_link->sof_timestamp < + sync_frame_duration / 5) && + (sync_rd_slot->sync_mode == CAM_REQ_MGR_SYNC_MODE_SYNC)) { + + /* + * This means current frame should sync with next + * frame of sync link, then the request id of in + * rd slot of two links should be same. + */ + CAM_DBG(CAM_CRM, + "link %x req_id %lld, sync_link %x req_id %lld", + link->link_hdl, req_id, + sync_link->link_hdl, sync_req_id); + + if (req_id > sync_req_id) { + CAM_DBG(CAM_CRM, + "link %x too quickly, skip this frame", + link->link_hdl); + return -EAGAIN; + } else if (req_id < sync_req_id) { + CAM_DBG(CAM_CRM, + "sync link %x too quickly, skip next frame of sync link", + sync_link->link_hdl); + link->sync_link_sof_skip = true; + } + } + CAM_DBG(CAM_REQ, "Req: %lld ready to apply on link: %x [validation successful]", req_id, link->link_hdl);