Loading drivers/cam_req_mgr/cam_req_mgr_core.c +138 −123 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ static struct cam_req_mgr_core_link g_links[MAXIMUM_LINKS_PER_SESSION]; void cam_req_mgr_core_link_reset(struct cam_req_mgr_core_link *link) { uint32_t pd = 0; int i = 0; link->link_hdl = 0; link->num_devs = 0; Loading @@ -37,7 +38,6 @@ void cam_req_mgr_core_link_reset(struct cam_req_mgr_core_link *link) link->parent = NULL; link->subscribe_event = 0; link->trigger_mask = 0; link->sync_link = 0; link->sync_link_sof_skip = false; link->open_req_cnt = 0; link->last_flush_id = 0; Loading @@ -52,12 +52,16 @@ void cam_req_mgr_core_link_reset(struct cam_req_mgr_core_link *link) link->sof_timestamp = 0; link->prev_sof_timestamp = 0; link->skip_init_frame = false; link->num_sync_links = 0; atomic_set(&link->eof_event_cnt, 0); for (pd = 0; pd < CAM_PIPELINE_DELAY_MAX; pd++) { link->req.apply_data[pd].req_id = -1; link->req.prev_apply_data[pd].req_id = -1; } for (i = 0; i < MAXIMUM_LINKS_PER_SESSION - 1; i++) link->sync_link[i] = NULL; } void cam_req_mgr_handle_core_shutdown(void) Loading Loading @@ -1100,20 +1104,19 @@ static int32_t __cam_req_mgr_find_slot_for_req( */ static int __cam_req_mgr_check_sync_for_mslave( struct cam_req_mgr_core_link *link, struct cam_req_mgr_core_link *sync_link, struct cam_req_mgr_slot *slot) { struct cam_req_mgr_core_link *sync_link = NULL; struct cam_req_mgr_slot *sync_slot = NULL; int sync_slot_idx = 0, prev_idx, next_idx, rd_idx, sync_rd_idx, rc = 0; int64_t req_id = 0, sync_req_id = 0; int32_t sync_num_slots = 0; if (!link->sync_link) { if (!sync_link) { CAM_ERR(CAM_CRM, "Sync link null"); return -EINVAL; } 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; Loading Loading @@ -1288,15 +1291,6 @@ static int __cam_req_mgr_check_sync_for_mslave( "Req: %lld ready to apply on link: %x [validation successful]", req_id, link->link_hdl); /* * At this point all validation is successfully done * and we can proceed to apply the given request. * Ideally the next call should return success. */ rc = __cam_req_mgr_check_link_is_ready(link, slot->idx, false); if (rc) CAM_WARN(CAM_CRM, "Unexpected return value rc: %d", rc); return 0; } Loading @@ -1313,9 +1307,9 @@ static int __cam_req_mgr_check_sync_for_mslave( */ static int __cam_req_mgr_check_sync_req_is_ready( struct cam_req_mgr_core_link *link, struct cam_req_mgr_core_link *sync_link, struct cam_req_mgr_slot *slot) { struct cam_req_mgr_core_link *sync_link = NULL; 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; Loading @@ -1325,12 +1319,11 @@ static int __cam_req_mgr_check_sync_req_is_ready( uint64_t master_slave_diff = 0; bool ready = true, sync_ready = true; if (!link->sync_link) { if (!sync_link) { CAM_ERR(CAM_CRM, "Sync link null"); return -EINVAL; } 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; Loading Loading @@ -1520,6 +1513,50 @@ static int __cam_req_mgr_check_sync_req_is_ready( "Req: %lld ready to apply on link: %x [validation successful]", req_id, link->link_hdl); return 0; } static int __cam_req_mgr_check_multi_sync_link_ready( struct cam_req_mgr_core_link *link, struct cam_req_mgr_slot *slot) { int i, rc = 0; for (i = 0; i < link->num_sync_links; i++) { if (link->sync_link[i]) { if (link->max_delay == link->sync_link[i]->max_delay) { rc = __cam_req_mgr_check_sync_req_is_ready( link, link->sync_link[i], slot); if (rc < 0) { CAM_DBG(CAM_CRM, "link %x not ready", link->link_hdl); return rc; } } else if (link->max_delay > link->sync_link[i]->max_delay) { link->is_master = true; link->sync_link[i]->is_master = false; rc = __cam_req_mgr_check_sync_for_mslave( link, link->sync_link[i], slot); if (rc < 0) { CAM_DBG(CAM_CRM, "link%x not ready", link->link_hdl); return rc; } } else { link->is_master = false; link->sync_link[i]->is_master = true; rc = __cam_req_mgr_check_sync_for_mslave( link, link->sync_link[i], slot); if (rc < 0) { CAM_DBG(CAM_CRM, "link %x not ready", link->link_hdl); return rc; } } } } /* * At this point all validation is successfully done * and we can proceed to apply the given request. Loading @@ -1545,13 +1582,14 @@ static int __cam_req_mgr_check_sync_req_is_ready( static int __cam_req_mgr_process_req(struct cam_req_mgr_core_link *link, struct cam_req_mgr_trigger_notify *trigger_data) { int rc = 0, idx; int rc = 0, idx, i; int reset_step = 0; uint32_t trigger = trigger_data->trigger; struct cam_req_mgr_slot *slot = NULL; struct cam_req_mgr_req_queue *in_q; struct cam_req_mgr_core_session *session; struct cam_req_mgr_connected_device *dev; struct cam_req_mgr_core_link *tmp_link = NULL; in_q = link->req.in_q; session = (struct cam_req_mgr_core_session *)link->parent; Loading Loading @@ -1602,22 +1640,9 @@ static int __cam_req_mgr_process_req(struct cam_req_mgr_core_link *link, goto error; } if ((slot->sync_mode == CAM_REQ_MGR_SYNC_MODE_SYNC) && (link->sync_link)) { if (link->is_master || link->sync_link->is_master) { if (!link->in_msync_mode) { CAM_DBG(CAM_CRM, "Settings master-slave sync mode for link 0x%x", link->link_hdl); link->in_msync_mode = true; } rc = __cam_req_mgr_check_sync_for_mslave( link, slot); } else { rc = __cam_req_mgr_check_sync_req_is_ready( if (slot->sync_mode == CAM_REQ_MGR_SYNC_MODE_SYNC) { rc = __cam_req_mgr_check_multi_sync_link_ready( link, slot); } } else { if (link->in_msync_mode) { CAM_DBG(CAM_CRM, Loading @@ -1625,9 +1650,12 @@ static int __cam_req_mgr_process_req(struct cam_req_mgr_core_link *link, link->link_hdl); link->in_msync_mode = false; link->initial_sync_req = -1; if (link->sync_link) { link->sync_link->initial_sync_req = -1; link->sync_link->in_msync_mode = false; for (i = 0; i < link->num_sync_links; i++) { if (link->sync_link[i]) { tmp_link = link->sync_link[i]; tmp_link->initial_sync_req = -1; tmp_link->in_msync_mode = false; } } } Loading Loading @@ -1715,11 +1743,15 @@ static int __cam_req_mgr_process_req(struct cam_req_mgr_core_link *link, link->link_hdl); idx = in_q->rd_idx; reset_step = link->max_delay; if (link->sync_link) { for (i = 0; i < link->num_sync_links; i++) { if (link->sync_link[i]) { if ((link->in_msync_mode) && (link->sync_link->is_master)) (link->sync_link[i]->max_delay > reset_step)) reset_step = link->sync_link->max_delay; link->sync_link[i]->max_delay; } } if (slot->req_id > 0) Loading Loading @@ -2160,7 +2192,10 @@ static struct cam_req_mgr_core_link *__cam_req_mgr_reserve_link( in_q->num_slots = 0; link->state = CAM_CRM_LINK_STATE_IDLE; link->parent = (void *)session; link->sync_link = NULL; for (i = 0; i < MAXIMUM_LINKS_PER_SESSION - 1; i++) link->sync_link[i] = NULL; mutex_unlock(&link->lock); mutex_lock(&session->lock); Loading Loading @@ -2223,7 +2258,7 @@ static void __cam_req_mgr_unreserve_link( struct cam_req_mgr_core_session *session, struct cam_req_mgr_core_link *link) { int i; int i, j; if (!session || !link) { CAM_ERR(CAM_CRM, "NULL session/link ptr %pK %pK", Loading @@ -2242,14 +2277,16 @@ static void __cam_req_mgr_unreserve_link( for (i = 0; i < MAXIMUM_LINKS_PER_SESSION; i++) { if (session->links[i] == link) session->links[i] = NULL; if (link->sync_link) { if (link->sync_link == session->links[i]) session->links[i]->sync_link = NULL; for (j = 0; j < MAXIMUM_LINKS_PER_SESSION - 1; j++) { if (link->sync_link[j]) { if (link->sync_link[j] == session->links[i]) session->links[i]->sync_link[j] = NULL; } } } link->sync_link = NULL; for (j = 0; j < MAXIMUM_LINKS_PER_SESSION - 1; j++) link->sync_link[j] = NULL; session->num_links--; CAM_DBG(CAM_CRM, "Active session links (%d)", session->num_links); mutex_unlock(&session->lock); Loading Loading @@ -2361,7 +2398,7 @@ int cam_req_mgr_process_flush_req(void *priv, void *data) */ int cam_req_mgr_process_sched_req(void *priv, void *data) { int rc = 0; int rc = 0, i; struct cam_req_mgr_sched_request *sched_req = NULL; struct cam_req_mgr_core_link *link = NULL; struct cam_req_mgr_req_queue *in_q = NULL; Loading Loading @@ -2421,8 +2458,10 @@ int cam_req_mgr_process_sched_req(void *priv, void *data) link->initial_sync_req = slot->req_id; } else { link->initial_sync_req = -1; if (link->sync_link) link->sync_link->initial_sync_req = -1; for (i = 0; i < link->num_sync_links; i++) { if (link->sync_link[i]) link->sync_link[i]->initial_sync_req = -1; } } mutex_unlock(&link->req.lock); Loading Loading @@ -2655,7 +2694,7 @@ int cam_req_mgr_process_error(void *priv, void *data) __cam_req_mgr_tbl_set_all_skip_cnt(&link->req.l_tbl); in_q->rd_idx = idx; in_q->slot[idx].status = CRM_SLOT_STATUS_REQ_ADDED; if (link->sync_link) { if (link->sync_link[0]) { in_q->slot[idx].sync_mode = 0; __cam_req_mgr_inc_idx(&idx, 1, link->req.l_tbl->num_slots); Loading Loading @@ -3897,40 +3936,13 @@ int cam_req_mgr_schedule_request( return rc; } /** * __cam_req_mgr_set_master_link() * * @brief : Each links sets its max pd delay based on the devices on the * link. The link with higher pd is assigned master. * @link1 : One of the sync links * @link2 : The other sync link */ static void __cam_req_mgr_set_master_link( struct cam_req_mgr_core_link *link1, struct cam_req_mgr_core_link *link2) { if (link1->max_delay > link2->max_delay) { link1->is_master = true; link2->initial_skip = true; } else if (link2->max_delay > link1->max_delay) { link2->is_master = true; link1->initial_skip = true; } CAM_DBG(CAM_CRM, "link_hdl1[0x%x] is_master [%u] link_hdl2[0x%x] is_master[%u]", link1->link_hdl, link1->is_master, link2->link_hdl, link2->is_master); } int cam_req_mgr_sync_config( struct cam_req_mgr_sync_mode *sync_info) { int rc = 0; int i, j, rc = 0; int sync_idx = 0; struct cam_req_mgr_core_session *cam_session; struct cam_req_mgr_core_link *link1 = NULL; struct cam_req_mgr_core_link *link2 = NULL; struct cam_req_mgr_core_link *link[MAX_LINKS_PER_SESSION]; if (!sync_info) { CAM_ERR(CAM_CRM, "NULL pointer"); Loading Loading @@ -3968,58 +3980,61 @@ int cam_req_mgr_sync_config( mutex_lock(&cam_session->lock); CAM_DBG(CAM_CRM, "link handles %x %x", sync_info->link_hdls[0], sync_info->link_hdls[1]); for (i = 0; i < sync_info->num_links; i++) { /* only two links existing per session in dual cam use case*/ link1 = cam_get_device_priv(sync_info->link_hdls[0]); if (!link1) { CAM_ERR(CAM_CRM, "link1 NULL pointer"); if (!sync_info->link_hdls[i]) { CAM_ERR(CAM_CRM, "link handle %d is null", i); rc = -EINVAL; goto done; } link2 = cam_get_device_priv(sync_info->link_hdls[1]); if (!link2) { CAM_ERR(CAM_CRM, "link2 NULL pointer"); link[i] = cam_get_device_priv(sync_info->link_hdls[i]); if (!link[i]) { CAM_ERR(CAM_CRM, "link%d NULL pointer", i); rc = -EINVAL; goto done; } link1->sync_link_sof_skip = false; link1->sync_link = NULL; link2->sync_link_sof_skip = false; link2->sync_link = NULL; link[i]->sync_link_sof_skip = false; link[i]->is_master = false; link[i]->in_msync_mode = false; link[i]->initial_sync_req = -1; link1->is_master = false; link2->is_master = false; link1->in_msync_mode = false; link2->in_msync_mode = false; link1->initial_sync_req = -1; link2->initial_sync_req = -1; for (j = 0; j < sync_info->num_links-1; j++) link[i]->sync_link[j] = NULL; } if (sync_info->sync_mode == CAM_REQ_MGR_SYNC_MODE_SYNC) { link1->sync_link = link2; link2->sync_link = link1; __cam_req_mgr_set_master_link(link1, link2); for (i = 0; i < sync_info->num_links; i++) { j = 0; sync_idx = 0; CAM_DBG(CAM_REQ, "link %x adds sync link:", link[i]->link_hdl); while (j < sync_info->num_links) { if (i != j) { link[i]->sync_link[sync_idx++] = link[j]; link[i]->num_sync_links++; CAM_DBG(CAM_REQ, "sync_link[%d] : %x", sync_idx-1, link[j]->link_hdl); } j++; } link[i]->initial_skip = true; link[i]->sof_timestamp = 0; } } else { /* * Reset below info after the mode is configured * to NO-SYNC mode since they may be overridden * if the sync config is invoked after SOF comes. */ link1->initial_skip = true; link2->initial_skip = true; link1->sof_timestamp = 0; link2->sof_timestamp = 0; for (j = 0; j < sync_info->num_links; j++) { link[j]->initial_skip = true; link[j]->sof_timestamp = 0; link[j]->num_sync_links = 0; } } cam_session->sync_mode = sync_info->sync_mode; CAM_DBG(CAM_REQ, "Sync config on link1 0x%x & link2 0x%x with sync_mode %d", link1->link_hdl, link2->link_hdl, cam_session->sync_mode); "Sync config completed on %d links with sync_mode %d", sync_info->num_links, sync_info->sync_mode); done: mutex_unlock(&cam_session->lock); Loading drivers/cam_req_mgr/cam_req_mgr_core.h +5 −2 Original line number Diff line number Diff line Loading @@ -343,7 +343,8 @@ struct cam_req_mgr_connected_device { * @subscribe_event : irqs that link subscribes, IFE should send * notification to CRM at those hw events. * @trigger_mask : mask on which irq the req is already applied * @sync_link : pointer to the sync link for synchronization * @sync_link : array of pointer to the sync link for synchronization * @num_sync_links : num of links sync associated with this link * @sync_link_sof_skip : flag determines if a pkt is not available for a given * frame in a particular link skip corresponding * frame in sync link as well. Loading Loading @@ -387,7 +388,9 @@ struct cam_req_mgr_core_link { spinlock_t link_state_spin_lock; uint32_t subscribe_event; uint32_t trigger_mask; struct cam_req_mgr_core_link *sync_link; struct cam_req_mgr_core_link *sync_link[MAXIMUM_LINKS_PER_SESSION - 1]; int32_t num_sync_links; bool sync_link_sof_skip; int32_t open_req_cnt; uint32_t last_flush_id; Loading Loading
drivers/cam_req_mgr/cam_req_mgr_core.c +138 −123 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ static struct cam_req_mgr_core_link g_links[MAXIMUM_LINKS_PER_SESSION]; void cam_req_mgr_core_link_reset(struct cam_req_mgr_core_link *link) { uint32_t pd = 0; int i = 0; link->link_hdl = 0; link->num_devs = 0; Loading @@ -37,7 +38,6 @@ void cam_req_mgr_core_link_reset(struct cam_req_mgr_core_link *link) link->parent = NULL; link->subscribe_event = 0; link->trigger_mask = 0; link->sync_link = 0; link->sync_link_sof_skip = false; link->open_req_cnt = 0; link->last_flush_id = 0; Loading @@ -52,12 +52,16 @@ void cam_req_mgr_core_link_reset(struct cam_req_mgr_core_link *link) link->sof_timestamp = 0; link->prev_sof_timestamp = 0; link->skip_init_frame = false; link->num_sync_links = 0; atomic_set(&link->eof_event_cnt, 0); for (pd = 0; pd < CAM_PIPELINE_DELAY_MAX; pd++) { link->req.apply_data[pd].req_id = -1; link->req.prev_apply_data[pd].req_id = -1; } for (i = 0; i < MAXIMUM_LINKS_PER_SESSION - 1; i++) link->sync_link[i] = NULL; } void cam_req_mgr_handle_core_shutdown(void) Loading Loading @@ -1100,20 +1104,19 @@ static int32_t __cam_req_mgr_find_slot_for_req( */ static int __cam_req_mgr_check_sync_for_mslave( struct cam_req_mgr_core_link *link, struct cam_req_mgr_core_link *sync_link, struct cam_req_mgr_slot *slot) { struct cam_req_mgr_core_link *sync_link = NULL; struct cam_req_mgr_slot *sync_slot = NULL; int sync_slot_idx = 0, prev_idx, next_idx, rd_idx, sync_rd_idx, rc = 0; int64_t req_id = 0, sync_req_id = 0; int32_t sync_num_slots = 0; if (!link->sync_link) { if (!sync_link) { CAM_ERR(CAM_CRM, "Sync link null"); return -EINVAL; } 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; Loading Loading @@ -1288,15 +1291,6 @@ static int __cam_req_mgr_check_sync_for_mslave( "Req: %lld ready to apply on link: %x [validation successful]", req_id, link->link_hdl); /* * At this point all validation is successfully done * and we can proceed to apply the given request. * Ideally the next call should return success. */ rc = __cam_req_mgr_check_link_is_ready(link, slot->idx, false); if (rc) CAM_WARN(CAM_CRM, "Unexpected return value rc: %d", rc); return 0; } Loading @@ -1313,9 +1307,9 @@ static int __cam_req_mgr_check_sync_for_mslave( */ static int __cam_req_mgr_check_sync_req_is_ready( struct cam_req_mgr_core_link *link, struct cam_req_mgr_core_link *sync_link, struct cam_req_mgr_slot *slot) { struct cam_req_mgr_core_link *sync_link = NULL; 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; Loading @@ -1325,12 +1319,11 @@ static int __cam_req_mgr_check_sync_req_is_ready( uint64_t master_slave_diff = 0; bool ready = true, sync_ready = true; if (!link->sync_link) { if (!sync_link) { CAM_ERR(CAM_CRM, "Sync link null"); return -EINVAL; } 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; Loading Loading @@ -1520,6 +1513,50 @@ static int __cam_req_mgr_check_sync_req_is_ready( "Req: %lld ready to apply on link: %x [validation successful]", req_id, link->link_hdl); return 0; } static int __cam_req_mgr_check_multi_sync_link_ready( struct cam_req_mgr_core_link *link, struct cam_req_mgr_slot *slot) { int i, rc = 0; for (i = 0; i < link->num_sync_links; i++) { if (link->sync_link[i]) { if (link->max_delay == link->sync_link[i]->max_delay) { rc = __cam_req_mgr_check_sync_req_is_ready( link, link->sync_link[i], slot); if (rc < 0) { CAM_DBG(CAM_CRM, "link %x not ready", link->link_hdl); return rc; } } else if (link->max_delay > link->sync_link[i]->max_delay) { link->is_master = true; link->sync_link[i]->is_master = false; rc = __cam_req_mgr_check_sync_for_mslave( link, link->sync_link[i], slot); if (rc < 0) { CAM_DBG(CAM_CRM, "link%x not ready", link->link_hdl); return rc; } } else { link->is_master = false; link->sync_link[i]->is_master = true; rc = __cam_req_mgr_check_sync_for_mslave( link, link->sync_link[i], slot); if (rc < 0) { CAM_DBG(CAM_CRM, "link %x not ready", link->link_hdl); return rc; } } } } /* * At this point all validation is successfully done * and we can proceed to apply the given request. Loading @@ -1545,13 +1582,14 @@ static int __cam_req_mgr_check_sync_req_is_ready( static int __cam_req_mgr_process_req(struct cam_req_mgr_core_link *link, struct cam_req_mgr_trigger_notify *trigger_data) { int rc = 0, idx; int rc = 0, idx, i; int reset_step = 0; uint32_t trigger = trigger_data->trigger; struct cam_req_mgr_slot *slot = NULL; struct cam_req_mgr_req_queue *in_q; struct cam_req_mgr_core_session *session; struct cam_req_mgr_connected_device *dev; struct cam_req_mgr_core_link *tmp_link = NULL; in_q = link->req.in_q; session = (struct cam_req_mgr_core_session *)link->parent; Loading Loading @@ -1602,22 +1640,9 @@ static int __cam_req_mgr_process_req(struct cam_req_mgr_core_link *link, goto error; } if ((slot->sync_mode == CAM_REQ_MGR_SYNC_MODE_SYNC) && (link->sync_link)) { if (link->is_master || link->sync_link->is_master) { if (!link->in_msync_mode) { CAM_DBG(CAM_CRM, "Settings master-slave sync mode for link 0x%x", link->link_hdl); link->in_msync_mode = true; } rc = __cam_req_mgr_check_sync_for_mslave( link, slot); } else { rc = __cam_req_mgr_check_sync_req_is_ready( if (slot->sync_mode == CAM_REQ_MGR_SYNC_MODE_SYNC) { rc = __cam_req_mgr_check_multi_sync_link_ready( link, slot); } } else { if (link->in_msync_mode) { CAM_DBG(CAM_CRM, Loading @@ -1625,9 +1650,12 @@ static int __cam_req_mgr_process_req(struct cam_req_mgr_core_link *link, link->link_hdl); link->in_msync_mode = false; link->initial_sync_req = -1; if (link->sync_link) { link->sync_link->initial_sync_req = -1; link->sync_link->in_msync_mode = false; for (i = 0; i < link->num_sync_links; i++) { if (link->sync_link[i]) { tmp_link = link->sync_link[i]; tmp_link->initial_sync_req = -1; tmp_link->in_msync_mode = false; } } } Loading Loading @@ -1715,11 +1743,15 @@ static int __cam_req_mgr_process_req(struct cam_req_mgr_core_link *link, link->link_hdl); idx = in_q->rd_idx; reset_step = link->max_delay; if (link->sync_link) { for (i = 0; i < link->num_sync_links; i++) { if (link->sync_link[i]) { if ((link->in_msync_mode) && (link->sync_link->is_master)) (link->sync_link[i]->max_delay > reset_step)) reset_step = link->sync_link->max_delay; link->sync_link[i]->max_delay; } } if (slot->req_id > 0) Loading Loading @@ -2160,7 +2192,10 @@ static struct cam_req_mgr_core_link *__cam_req_mgr_reserve_link( in_q->num_slots = 0; link->state = CAM_CRM_LINK_STATE_IDLE; link->parent = (void *)session; link->sync_link = NULL; for (i = 0; i < MAXIMUM_LINKS_PER_SESSION - 1; i++) link->sync_link[i] = NULL; mutex_unlock(&link->lock); mutex_lock(&session->lock); Loading Loading @@ -2223,7 +2258,7 @@ static void __cam_req_mgr_unreserve_link( struct cam_req_mgr_core_session *session, struct cam_req_mgr_core_link *link) { int i; int i, j; if (!session || !link) { CAM_ERR(CAM_CRM, "NULL session/link ptr %pK %pK", Loading @@ -2242,14 +2277,16 @@ static void __cam_req_mgr_unreserve_link( for (i = 0; i < MAXIMUM_LINKS_PER_SESSION; i++) { if (session->links[i] == link) session->links[i] = NULL; if (link->sync_link) { if (link->sync_link == session->links[i]) session->links[i]->sync_link = NULL; for (j = 0; j < MAXIMUM_LINKS_PER_SESSION - 1; j++) { if (link->sync_link[j]) { if (link->sync_link[j] == session->links[i]) session->links[i]->sync_link[j] = NULL; } } } link->sync_link = NULL; for (j = 0; j < MAXIMUM_LINKS_PER_SESSION - 1; j++) link->sync_link[j] = NULL; session->num_links--; CAM_DBG(CAM_CRM, "Active session links (%d)", session->num_links); mutex_unlock(&session->lock); Loading Loading @@ -2361,7 +2398,7 @@ int cam_req_mgr_process_flush_req(void *priv, void *data) */ int cam_req_mgr_process_sched_req(void *priv, void *data) { int rc = 0; int rc = 0, i; struct cam_req_mgr_sched_request *sched_req = NULL; struct cam_req_mgr_core_link *link = NULL; struct cam_req_mgr_req_queue *in_q = NULL; Loading Loading @@ -2421,8 +2458,10 @@ int cam_req_mgr_process_sched_req(void *priv, void *data) link->initial_sync_req = slot->req_id; } else { link->initial_sync_req = -1; if (link->sync_link) link->sync_link->initial_sync_req = -1; for (i = 0; i < link->num_sync_links; i++) { if (link->sync_link[i]) link->sync_link[i]->initial_sync_req = -1; } } mutex_unlock(&link->req.lock); Loading Loading @@ -2655,7 +2694,7 @@ int cam_req_mgr_process_error(void *priv, void *data) __cam_req_mgr_tbl_set_all_skip_cnt(&link->req.l_tbl); in_q->rd_idx = idx; in_q->slot[idx].status = CRM_SLOT_STATUS_REQ_ADDED; if (link->sync_link) { if (link->sync_link[0]) { in_q->slot[idx].sync_mode = 0; __cam_req_mgr_inc_idx(&idx, 1, link->req.l_tbl->num_slots); Loading Loading @@ -3897,40 +3936,13 @@ int cam_req_mgr_schedule_request( return rc; } /** * __cam_req_mgr_set_master_link() * * @brief : Each links sets its max pd delay based on the devices on the * link. The link with higher pd is assigned master. * @link1 : One of the sync links * @link2 : The other sync link */ static void __cam_req_mgr_set_master_link( struct cam_req_mgr_core_link *link1, struct cam_req_mgr_core_link *link2) { if (link1->max_delay > link2->max_delay) { link1->is_master = true; link2->initial_skip = true; } else if (link2->max_delay > link1->max_delay) { link2->is_master = true; link1->initial_skip = true; } CAM_DBG(CAM_CRM, "link_hdl1[0x%x] is_master [%u] link_hdl2[0x%x] is_master[%u]", link1->link_hdl, link1->is_master, link2->link_hdl, link2->is_master); } int cam_req_mgr_sync_config( struct cam_req_mgr_sync_mode *sync_info) { int rc = 0; int i, j, rc = 0; int sync_idx = 0; struct cam_req_mgr_core_session *cam_session; struct cam_req_mgr_core_link *link1 = NULL; struct cam_req_mgr_core_link *link2 = NULL; struct cam_req_mgr_core_link *link[MAX_LINKS_PER_SESSION]; if (!sync_info) { CAM_ERR(CAM_CRM, "NULL pointer"); Loading Loading @@ -3968,58 +3980,61 @@ int cam_req_mgr_sync_config( mutex_lock(&cam_session->lock); CAM_DBG(CAM_CRM, "link handles %x %x", sync_info->link_hdls[0], sync_info->link_hdls[1]); for (i = 0; i < sync_info->num_links; i++) { /* only two links existing per session in dual cam use case*/ link1 = cam_get_device_priv(sync_info->link_hdls[0]); if (!link1) { CAM_ERR(CAM_CRM, "link1 NULL pointer"); if (!sync_info->link_hdls[i]) { CAM_ERR(CAM_CRM, "link handle %d is null", i); rc = -EINVAL; goto done; } link2 = cam_get_device_priv(sync_info->link_hdls[1]); if (!link2) { CAM_ERR(CAM_CRM, "link2 NULL pointer"); link[i] = cam_get_device_priv(sync_info->link_hdls[i]); if (!link[i]) { CAM_ERR(CAM_CRM, "link%d NULL pointer", i); rc = -EINVAL; goto done; } link1->sync_link_sof_skip = false; link1->sync_link = NULL; link2->sync_link_sof_skip = false; link2->sync_link = NULL; link[i]->sync_link_sof_skip = false; link[i]->is_master = false; link[i]->in_msync_mode = false; link[i]->initial_sync_req = -1; link1->is_master = false; link2->is_master = false; link1->in_msync_mode = false; link2->in_msync_mode = false; link1->initial_sync_req = -1; link2->initial_sync_req = -1; for (j = 0; j < sync_info->num_links-1; j++) link[i]->sync_link[j] = NULL; } if (sync_info->sync_mode == CAM_REQ_MGR_SYNC_MODE_SYNC) { link1->sync_link = link2; link2->sync_link = link1; __cam_req_mgr_set_master_link(link1, link2); for (i = 0; i < sync_info->num_links; i++) { j = 0; sync_idx = 0; CAM_DBG(CAM_REQ, "link %x adds sync link:", link[i]->link_hdl); while (j < sync_info->num_links) { if (i != j) { link[i]->sync_link[sync_idx++] = link[j]; link[i]->num_sync_links++; CAM_DBG(CAM_REQ, "sync_link[%d] : %x", sync_idx-1, link[j]->link_hdl); } j++; } link[i]->initial_skip = true; link[i]->sof_timestamp = 0; } } else { /* * Reset below info after the mode is configured * to NO-SYNC mode since they may be overridden * if the sync config is invoked after SOF comes. */ link1->initial_skip = true; link2->initial_skip = true; link1->sof_timestamp = 0; link2->sof_timestamp = 0; for (j = 0; j < sync_info->num_links; j++) { link[j]->initial_skip = true; link[j]->sof_timestamp = 0; link[j]->num_sync_links = 0; } } cam_session->sync_mode = sync_info->sync_mode; CAM_DBG(CAM_REQ, "Sync config on link1 0x%x & link2 0x%x with sync_mode %d", link1->link_hdl, link2->link_hdl, cam_session->sync_mode); "Sync config completed on %d links with sync_mode %d", sync_info->num_links, sync_info->sync_mode); done: mutex_unlock(&cam_session->lock); Loading
drivers/cam_req_mgr/cam_req_mgr_core.h +5 −2 Original line number Diff line number Diff line Loading @@ -343,7 +343,8 @@ struct cam_req_mgr_connected_device { * @subscribe_event : irqs that link subscribes, IFE should send * notification to CRM at those hw events. * @trigger_mask : mask on which irq the req is already applied * @sync_link : pointer to the sync link for synchronization * @sync_link : array of pointer to the sync link for synchronization * @num_sync_links : num of links sync associated with this link * @sync_link_sof_skip : flag determines if a pkt is not available for a given * frame in a particular link skip corresponding * frame in sync link as well. Loading Loading @@ -387,7 +388,9 @@ struct cam_req_mgr_core_link { spinlock_t link_state_spin_lock; uint32_t subscribe_event; uint32_t trigger_mask; struct cam_req_mgr_core_link *sync_link; struct cam_req_mgr_core_link *sync_link[MAXIMUM_LINKS_PER_SESSION - 1]; int32_t num_sync_links; bool sync_link_sof_skip; int32_t open_req_cnt; uint32_t last_flush_id; Loading