Loading drivers/cam_isp/cam_isp_context.c +6 −0 Original line number Diff line number Diff line Loading @@ -1313,6 +1313,7 @@ static int __cam_isp_ctx_notify_sof_in_activated_state( notify.trigger = CAM_TRIGGER_POINT_SOF; notify.req_id = ctx_isp->req_info.last_bufdone_req_id; notify.sof_timestamp_val = ctx_isp->sof_timestamp_val; notify.trigger_id = ctx_isp->trigger_id; ctx->ctx_crm_intf->notify_trigger(¬ify); CAM_DBG(CAM_ISP, "Notify CRM SOF frame %lld ctx %u", Loading Loading @@ -4517,6 +4518,7 @@ static int __cam_isp_ctx_link_in_acquired(struct cam_context *ctx, ctx->link_hdl = link->link_hdl; ctx->ctx_crm_intf = link->crm_cb; ctx_isp->subscribe_event = link->subscribe_event; ctx_isp->trigger_id = link->trigger_id; /* change state only if we had the init config */ if (ctx_isp->init_received) { Loading @@ -4533,9 +4535,12 @@ static int __cam_isp_ctx_unlink_in_acquired(struct cam_context *ctx, struct cam_req_mgr_core_dev_link_setup *unlink) { int rc = 0; struct cam_isp_context *ctx_isp = (struct cam_isp_context *) ctx->ctx_priv; ctx->link_hdl = -1; ctx->ctx_crm_intf = NULL; ctx_isp->trigger_id = -1; return rc; } Loading @@ -4550,6 +4555,7 @@ static int __cam_isp_ctx_get_dev_info_in_acquired(struct cam_context *ctx, dev_info->dev_id = CAM_REQ_MGR_DEVICE_IFE; dev_info->p_delay = 1; dev_info->trigger = CAM_TRIGGER_POINT_SOF; dev_info->trigger_on = true; return rc; } Loading drivers/cam_isp/cam_isp_context.h +2 −0 Original line number Diff line number Diff line Loading @@ -258,6 +258,7 @@ struct cam_isp_context_event_record { * @rxd_epoch: Indicate whether epoch has been received. Used to * decide whether to apply request in offline ctx * @workq: Worker thread for offline ife * @trigger_id: ID provided by CRM for each ctx on the link * */ struct cam_isp_context { Loading Loading @@ -300,6 +301,7 @@ struct cam_isp_context { uint32_t isp_device_type; atomic_t rxd_epoch; struct cam_req_mgr_core_workq *workq; int32_t trigger_id; }; /** Loading drivers/cam_req_mgr/cam_req_mgr_core.c +74 −3 Original line number Diff line number Diff line Loading @@ -40,6 +40,9 @@ void cam_req_mgr_core_link_reset(struct cam_req_mgr_core_link *link) link->open_req_cnt = 0; link->last_flush_id = 0; link->initial_sync_req = -1; link->dual_trigger = false; link->trigger_cnt[0] = 0; link->trigger_cnt[1] = 0; link->in_msync_mode = false; link->retry_cnt = 0; link->is_shutdown = false; Loading Loading @@ -2760,6 +2763,33 @@ static int cam_req_mgr_cb_notify_err( return rc; } static int __cam_req_mgr_check_for_dual_trigger( struct cam_req_mgr_core_link *link) { int rc = -EAGAIN; if (link->trigger_cnt[0] == link->trigger_cnt[1]) { link->trigger_cnt[0] = 0; link->trigger_cnt[1] = 0; rc = 0; return rc; } if ((link->trigger_cnt[0] && (link->trigger_cnt[0] - link->trigger_cnt[1] > 1)) || (link->trigger_cnt[1] && (link->trigger_cnt[1] - link->trigger_cnt[0] > 1))) { CAM_ERR(CAM_CRM, "One of the devices could not generate trigger"); return rc; } CAM_DBG(CAM_CRM, "Only one device has generated trigger"); return rc; } /** * cam_req_mgr_cb_notify_timer() * Loading Loading @@ -2878,7 +2908,7 @@ static int cam_req_mgr_cb_notify_stop( static int cam_req_mgr_cb_notify_trigger( struct cam_req_mgr_trigger_notify *trigger_data) { int rc = 0; int32_t rc = 0, trigger_id = 0; struct crm_workq_task *task = NULL; struct cam_req_mgr_core_link *link = NULL; struct cam_req_mgr_trigger_notify *notify_trigger; Loading @@ -2898,6 +2928,8 @@ static int cam_req_mgr_cb_notify_trigger( goto end; } trigger_id = trigger_data->trigger_id; spin_lock_bh(&link->link_state_spin_lock); if (link->state < CAM_CRM_LINK_STATE_READY) { CAM_WARN(CAM_CRM, "invalid link state:%d", link->state); Loading @@ -2909,6 +2941,23 @@ static int cam_req_mgr_cb_notify_trigger( if ((link->watchdog) && (link->watchdog->pause_timer)) link->watchdog->pause_timer = false; if (link->dual_trigger) { if ((trigger_id >= 0) && (trigger_id < CAM_REQ_MGR_MAX_TRIGGERS)) { link->trigger_cnt[trigger_id]++; rc = __cam_req_mgr_check_for_dual_trigger(link); if (rc) { spin_unlock_bh(&link->link_state_spin_lock); goto end; } } else { CAM_ERR(CAM_CRM, "trigger_id invalid %d", trigger_id); rc = -EINVAL; spin_unlock_bh(&link->link_state_spin_lock); goto end; } } crm_timer_reset(link->watchdog); spin_unlock_bh(&link->link_state_spin_lock); Loading Loading @@ -2963,6 +3012,7 @@ static int __cam_req_mgr_setup_link_info(struct cam_req_mgr_core_link *link, struct cam_req_mgr_req_tbl *pd_tbl; enum cam_pipeline_delay max_delay; uint32_t subscribe_event = 0; uint32_t num_trigger_devices = 0; if (link_info->version == VERSION_1) { if (link_info->u.link_info_v1.num_devices > CAM_REQ_MGR_MAX_HANDLES) Loading @@ -2973,6 +3023,7 @@ static int __cam_req_mgr_setup_link_info(struct cam_req_mgr_core_link *link, CAM_REQ_MGR_MAX_HANDLES_V2) return -EPERM; } mutex_init(&link->req.lock); CAM_DBG(CAM_CRM, "LOCK_DBG in_q lock %pK", &link->req.lock); link->req.num_tbl = 0; Loading Loading @@ -3052,6 +3103,17 @@ static int __cam_req_mgr_setup_link_info(struct cam_req_mgr_core_link *link, subscribe_event |= (uint32_t)dev->dev_info.trigger; } if (dev->dev_info.trigger_on) num_trigger_devices++; } if (num_trigger_devices > CAM_REQ_MGR_MAX_TRIGGERS) { CAM_ERR(CAM_CRM, "Unsupported number of trigger devices %u", num_trigger_devices); rc = -EINVAL; goto error; } link->subscribe_event = subscribe_event; Loading @@ -3060,7 +3122,10 @@ static int __cam_req_mgr_setup_link_info(struct cam_req_mgr_core_link *link, link_data.crm_cb = &cam_req_mgr_ops; link_data.max_delay = max_delay; link_data.subscribe_event = subscribe_event; if (num_trigger_devices == CAM_REQ_MGR_MAX_TRIGGERS) link->dual_trigger = true; num_trigger_devices = 0; for (i = 0; i < num_devices; i++) { dev = &link->l_dev[i]; Loading Loading @@ -3100,6 +3165,12 @@ static int __cam_req_mgr_setup_link_info(struct cam_req_mgr_core_link *link, CAM_DBG(CAM_CRM, "dev_bit %u name %s pd %u mask %d", dev->dev_bit, dev->dev_info.name, pd_tbl->pd, pd_tbl->dev_mask); link_data.trigger_id = -1; if ((dev->dev_info.trigger_on) && (link->dual_trigger)) { link_data.trigger_id = num_trigger_devices; num_trigger_devices++; } /* Communicate with dev to establish the link */ dev->ops->link_setup(&link_data); Loading drivers/cam_req_mgr/cam_req_mgr_core.h +7 −0 Original line number Diff line number Diff line Loading @@ -37,6 +37,7 @@ #define VERSION_1 1 #define VERSION_2 2 #define CAM_REQ_MGR_MAX_TRIGGERS 2 /** * enum crm_workq_task_type Loading Loading @@ -344,6 +345,9 @@ struct cam_req_mgr_connected_device { * as part of shutdown. * @sof_timestamp_value : SOF timestamp value * @prev_sof_timestamp : Previous SOF timestamp value * @dual_trigger : Links needs to wait for two triggers prior to * applying the settings * @trigger_cnt : trigger count value per device initiating the trigger */ struct cam_req_mgr_core_link { int32_t link_hdl; Loading Loading @@ -374,6 +378,9 @@ struct cam_req_mgr_core_link { bool is_shutdown; uint64_t sof_timestamp; uint64_t prev_sof_timestamp; bool dual_trigger; uint32_t trigger_cnt[CAM_REQ_MGR_MAX_TRIGGERS]; }; /** Loading drivers/cam_req_mgr/cam_req_mgr_interface.h +6 −0 Original line number Diff line number Diff line Loading @@ -210,6 +210,7 @@ enum cam_req_mgr_link_evt_type { * only to the devices which subscribe to this point. * @sof_timestamp_val: Captured time stamp value at sof hw event * @req_id : req id which returned buf_done * @trigger_id: ID to differentiate between the trigger devices */ struct cam_req_mgr_trigger_notify { int32_t link_hdl; Loading @@ -218,6 +219,7 @@ struct cam_req_mgr_trigger_notify { uint32_t trigger; uint64_t sof_timestamp_val; uint64_t req_id; int32_t trigger_id; }; /** Loading Loading @@ -286,6 +288,7 @@ struct cam_req_mgr_notify_stop { * @dev_id : device id info * @p_delay : delay between time settings applied and take effect * @trigger : Trigger point for the client * @trigger_on : This device provides trigger */ struct cam_req_mgr_device_info { int32_t dev_hdl; Loading @@ -293,6 +296,7 @@ struct cam_req_mgr_device_info { enum cam_req_mgr_device_id dev_id; enum cam_pipeline_delay p_delay; uint32_t trigger; bool trigger_on; }; /** Loading @@ -303,6 +307,7 @@ struct cam_req_mgr_device_info { * @max_delay : max pipeline delay on this link * @crm_cb : callback funcs to communicate with req mgr * @subscribe_event : the mask of trigger points this link subscribes * @trigger_id : Unique ID provided to the triggering device */ struct cam_req_mgr_core_dev_link_setup { int32_t link_enable; Loading @@ -311,6 +316,7 @@ struct cam_req_mgr_core_dev_link_setup { enum cam_pipeline_delay max_delay; struct cam_req_mgr_crm_cb *crm_cb; uint32_t subscribe_event; int32_t trigger_id; }; /** Loading Loading
drivers/cam_isp/cam_isp_context.c +6 −0 Original line number Diff line number Diff line Loading @@ -1313,6 +1313,7 @@ static int __cam_isp_ctx_notify_sof_in_activated_state( notify.trigger = CAM_TRIGGER_POINT_SOF; notify.req_id = ctx_isp->req_info.last_bufdone_req_id; notify.sof_timestamp_val = ctx_isp->sof_timestamp_val; notify.trigger_id = ctx_isp->trigger_id; ctx->ctx_crm_intf->notify_trigger(¬ify); CAM_DBG(CAM_ISP, "Notify CRM SOF frame %lld ctx %u", Loading Loading @@ -4517,6 +4518,7 @@ static int __cam_isp_ctx_link_in_acquired(struct cam_context *ctx, ctx->link_hdl = link->link_hdl; ctx->ctx_crm_intf = link->crm_cb; ctx_isp->subscribe_event = link->subscribe_event; ctx_isp->trigger_id = link->trigger_id; /* change state only if we had the init config */ if (ctx_isp->init_received) { Loading @@ -4533,9 +4535,12 @@ static int __cam_isp_ctx_unlink_in_acquired(struct cam_context *ctx, struct cam_req_mgr_core_dev_link_setup *unlink) { int rc = 0; struct cam_isp_context *ctx_isp = (struct cam_isp_context *) ctx->ctx_priv; ctx->link_hdl = -1; ctx->ctx_crm_intf = NULL; ctx_isp->trigger_id = -1; return rc; } Loading @@ -4550,6 +4555,7 @@ static int __cam_isp_ctx_get_dev_info_in_acquired(struct cam_context *ctx, dev_info->dev_id = CAM_REQ_MGR_DEVICE_IFE; dev_info->p_delay = 1; dev_info->trigger = CAM_TRIGGER_POINT_SOF; dev_info->trigger_on = true; return rc; } Loading
drivers/cam_isp/cam_isp_context.h +2 −0 Original line number Diff line number Diff line Loading @@ -258,6 +258,7 @@ struct cam_isp_context_event_record { * @rxd_epoch: Indicate whether epoch has been received. Used to * decide whether to apply request in offline ctx * @workq: Worker thread for offline ife * @trigger_id: ID provided by CRM for each ctx on the link * */ struct cam_isp_context { Loading Loading @@ -300,6 +301,7 @@ struct cam_isp_context { uint32_t isp_device_type; atomic_t rxd_epoch; struct cam_req_mgr_core_workq *workq; int32_t trigger_id; }; /** Loading
drivers/cam_req_mgr/cam_req_mgr_core.c +74 −3 Original line number Diff line number Diff line Loading @@ -40,6 +40,9 @@ void cam_req_mgr_core_link_reset(struct cam_req_mgr_core_link *link) link->open_req_cnt = 0; link->last_flush_id = 0; link->initial_sync_req = -1; link->dual_trigger = false; link->trigger_cnt[0] = 0; link->trigger_cnt[1] = 0; link->in_msync_mode = false; link->retry_cnt = 0; link->is_shutdown = false; Loading Loading @@ -2760,6 +2763,33 @@ static int cam_req_mgr_cb_notify_err( return rc; } static int __cam_req_mgr_check_for_dual_trigger( struct cam_req_mgr_core_link *link) { int rc = -EAGAIN; if (link->trigger_cnt[0] == link->trigger_cnt[1]) { link->trigger_cnt[0] = 0; link->trigger_cnt[1] = 0; rc = 0; return rc; } if ((link->trigger_cnt[0] && (link->trigger_cnt[0] - link->trigger_cnt[1] > 1)) || (link->trigger_cnt[1] && (link->trigger_cnt[1] - link->trigger_cnt[0] > 1))) { CAM_ERR(CAM_CRM, "One of the devices could not generate trigger"); return rc; } CAM_DBG(CAM_CRM, "Only one device has generated trigger"); return rc; } /** * cam_req_mgr_cb_notify_timer() * Loading Loading @@ -2878,7 +2908,7 @@ static int cam_req_mgr_cb_notify_stop( static int cam_req_mgr_cb_notify_trigger( struct cam_req_mgr_trigger_notify *trigger_data) { int rc = 0; int32_t rc = 0, trigger_id = 0; struct crm_workq_task *task = NULL; struct cam_req_mgr_core_link *link = NULL; struct cam_req_mgr_trigger_notify *notify_trigger; Loading @@ -2898,6 +2928,8 @@ static int cam_req_mgr_cb_notify_trigger( goto end; } trigger_id = trigger_data->trigger_id; spin_lock_bh(&link->link_state_spin_lock); if (link->state < CAM_CRM_LINK_STATE_READY) { CAM_WARN(CAM_CRM, "invalid link state:%d", link->state); Loading @@ -2909,6 +2941,23 @@ static int cam_req_mgr_cb_notify_trigger( if ((link->watchdog) && (link->watchdog->pause_timer)) link->watchdog->pause_timer = false; if (link->dual_trigger) { if ((trigger_id >= 0) && (trigger_id < CAM_REQ_MGR_MAX_TRIGGERS)) { link->trigger_cnt[trigger_id]++; rc = __cam_req_mgr_check_for_dual_trigger(link); if (rc) { spin_unlock_bh(&link->link_state_spin_lock); goto end; } } else { CAM_ERR(CAM_CRM, "trigger_id invalid %d", trigger_id); rc = -EINVAL; spin_unlock_bh(&link->link_state_spin_lock); goto end; } } crm_timer_reset(link->watchdog); spin_unlock_bh(&link->link_state_spin_lock); Loading Loading @@ -2963,6 +3012,7 @@ static int __cam_req_mgr_setup_link_info(struct cam_req_mgr_core_link *link, struct cam_req_mgr_req_tbl *pd_tbl; enum cam_pipeline_delay max_delay; uint32_t subscribe_event = 0; uint32_t num_trigger_devices = 0; if (link_info->version == VERSION_1) { if (link_info->u.link_info_v1.num_devices > CAM_REQ_MGR_MAX_HANDLES) Loading @@ -2973,6 +3023,7 @@ static int __cam_req_mgr_setup_link_info(struct cam_req_mgr_core_link *link, CAM_REQ_MGR_MAX_HANDLES_V2) return -EPERM; } mutex_init(&link->req.lock); CAM_DBG(CAM_CRM, "LOCK_DBG in_q lock %pK", &link->req.lock); link->req.num_tbl = 0; Loading Loading @@ -3052,6 +3103,17 @@ static int __cam_req_mgr_setup_link_info(struct cam_req_mgr_core_link *link, subscribe_event |= (uint32_t)dev->dev_info.trigger; } if (dev->dev_info.trigger_on) num_trigger_devices++; } if (num_trigger_devices > CAM_REQ_MGR_MAX_TRIGGERS) { CAM_ERR(CAM_CRM, "Unsupported number of trigger devices %u", num_trigger_devices); rc = -EINVAL; goto error; } link->subscribe_event = subscribe_event; Loading @@ -3060,7 +3122,10 @@ static int __cam_req_mgr_setup_link_info(struct cam_req_mgr_core_link *link, link_data.crm_cb = &cam_req_mgr_ops; link_data.max_delay = max_delay; link_data.subscribe_event = subscribe_event; if (num_trigger_devices == CAM_REQ_MGR_MAX_TRIGGERS) link->dual_trigger = true; num_trigger_devices = 0; for (i = 0; i < num_devices; i++) { dev = &link->l_dev[i]; Loading Loading @@ -3100,6 +3165,12 @@ static int __cam_req_mgr_setup_link_info(struct cam_req_mgr_core_link *link, CAM_DBG(CAM_CRM, "dev_bit %u name %s pd %u mask %d", dev->dev_bit, dev->dev_info.name, pd_tbl->pd, pd_tbl->dev_mask); link_data.trigger_id = -1; if ((dev->dev_info.trigger_on) && (link->dual_trigger)) { link_data.trigger_id = num_trigger_devices; num_trigger_devices++; } /* Communicate with dev to establish the link */ dev->ops->link_setup(&link_data); Loading
drivers/cam_req_mgr/cam_req_mgr_core.h +7 −0 Original line number Diff line number Diff line Loading @@ -37,6 +37,7 @@ #define VERSION_1 1 #define VERSION_2 2 #define CAM_REQ_MGR_MAX_TRIGGERS 2 /** * enum crm_workq_task_type Loading Loading @@ -344,6 +345,9 @@ struct cam_req_mgr_connected_device { * as part of shutdown. * @sof_timestamp_value : SOF timestamp value * @prev_sof_timestamp : Previous SOF timestamp value * @dual_trigger : Links needs to wait for two triggers prior to * applying the settings * @trigger_cnt : trigger count value per device initiating the trigger */ struct cam_req_mgr_core_link { int32_t link_hdl; Loading Loading @@ -374,6 +378,9 @@ struct cam_req_mgr_core_link { bool is_shutdown; uint64_t sof_timestamp; uint64_t prev_sof_timestamp; bool dual_trigger; uint32_t trigger_cnt[CAM_REQ_MGR_MAX_TRIGGERS]; }; /** Loading
drivers/cam_req_mgr/cam_req_mgr_interface.h +6 −0 Original line number Diff line number Diff line Loading @@ -210,6 +210,7 @@ enum cam_req_mgr_link_evt_type { * only to the devices which subscribe to this point. * @sof_timestamp_val: Captured time stamp value at sof hw event * @req_id : req id which returned buf_done * @trigger_id: ID to differentiate between the trigger devices */ struct cam_req_mgr_trigger_notify { int32_t link_hdl; Loading @@ -218,6 +219,7 @@ struct cam_req_mgr_trigger_notify { uint32_t trigger; uint64_t sof_timestamp_val; uint64_t req_id; int32_t trigger_id; }; /** Loading Loading @@ -286,6 +288,7 @@ struct cam_req_mgr_notify_stop { * @dev_id : device id info * @p_delay : delay between time settings applied and take effect * @trigger : Trigger point for the client * @trigger_on : This device provides trigger */ struct cam_req_mgr_device_info { int32_t dev_hdl; Loading @@ -293,6 +296,7 @@ struct cam_req_mgr_device_info { enum cam_req_mgr_device_id dev_id; enum cam_pipeline_delay p_delay; uint32_t trigger; bool trigger_on; }; /** Loading @@ -303,6 +307,7 @@ struct cam_req_mgr_device_info { * @max_delay : max pipeline delay on this link * @crm_cb : callback funcs to communicate with req mgr * @subscribe_event : the mask of trigger points this link subscribes * @trigger_id : Unique ID provided to the triggering device */ struct cam_req_mgr_core_dev_link_setup { int32_t link_enable; Loading @@ -311,6 +316,7 @@ struct cam_req_mgr_core_dev_link_setup { enum cam_pipeline_delay max_delay; struct cam_req_mgr_crm_cb *crm_cb; uint32_t subscribe_event; int32_t trigger_id; }; /** Loading