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

Commit bdb70816 authored by Jeyaprakash Soundrapandian's avatar Jeyaprakash Soundrapandian Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: camera: reqmgr: Add initial sync support" into dev/msm-4.14-camx

parents 7c77bf0f 39f0b2ba
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -703,6 +703,7 @@ static int __cam_isp_ctx_notify_sof_in_activated_state(
			notify.dev_hdl = ctx->dev_hdl;
			notify.frame_id = ctx_isp->frame_id;
			notify.trigger = CAM_TRIGGER_POINT_SOF;
			notify.sof_timestamp_val = ctx_isp->sof_timestamp_val;

			ctx->ctx_crm_intf->notify_trigger(&notify);
			CAM_DBG(CAM_ISP, "Notify CRM  SOF frame %lld ctx %u",
@@ -1335,6 +1336,7 @@ static int __cam_isp_ctx_fs2_sof_in_sof_state(
			notify.dev_hdl = ctx->dev_hdl;
			notify.frame_id = ctx_isp->frame_id;
			notify.trigger = CAM_TRIGGER_POINT_SOF;
			notify.sof_timestamp_val = ctx_isp->sof_timestamp_val;

			ctx->ctx_crm_intf->notify_trigger(&notify);
			CAM_DBG(CAM_ISP, "Notify CRM  SOF frame %lld",
@@ -1512,6 +1514,7 @@ static int __cam_isp_ctx_fs2_reg_upd_in_applied_state(
			notify.dev_hdl = ctx->dev_hdl;
			notify.frame_id = ctx_isp->frame_id;
			notify.trigger = CAM_TRIGGER_POINT_SOF;
			notify.sof_timestamp_val = ctx_isp->sof_timestamp_val;

			ctx->ctx_crm_intf->notify_trigger(&notify);
			CAM_DBG(CAM_ISP, "Notify CRM  SOF frame %lld",
@@ -2100,6 +2103,7 @@ static int __cam_isp_ctx_rdi_only_sof_in_top_state(
		notify.dev_hdl = ctx->dev_hdl;
		notify.frame_id = ctx_isp->frame_id;
		notify.trigger = CAM_TRIGGER_POINT_SOF;
		notify.sof_timestamp_val = ctx_isp->sof_timestamp_val;

		ctx->ctx_crm_intf->notify_trigger(&notify);
		CAM_DBG(CAM_ISP, "Notify CRM  SOF frame %lld",
@@ -2291,6 +2295,7 @@ static int __cam_isp_ctx_rdi_only_sof_in_bubble_state(
		notify.dev_hdl = ctx->dev_hdl;
		notify.frame_id = ctx_isp->frame_id;
		notify.trigger = CAM_TRIGGER_POINT_SOF;
		notify.sof_timestamp_val = ctx_isp->sof_timestamp_val;

		ctx->ctx_crm_intf->notify_trigger(&notify);
		CAM_DBG(CAM_ISP, "Notify CRM  SOF frame %lld",
@@ -2361,6 +2366,7 @@ static int __cam_isp_ctx_rdi_only_reg_upd_in_bubble_applied_state(
		notify.dev_hdl = ctx->dev_hdl;
		notify.frame_id = ctx_isp->frame_id;
		notify.trigger = CAM_TRIGGER_POINT_SOF;
		notify.sof_timestamp_val = ctx_isp->sof_timestamp_val;

		ctx->ctx_crm_intf->notify_trigger(&notify);
		CAM_DBG(CAM_ISP, "Notify CRM  SOF frame %lld",
+89 −4
Original line number Diff line number Diff line
@@ -48,6 +48,9 @@ void cam_req_mgr_core_link_reset(struct cam_req_mgr_core_link *link)
	link->last_flush_id = 0;
	link->initial_sync_req = -1;
	link->in_msync_mode = false;
	link->initial_skip = true;
	link->sof_timestamp = 0;
	link->prev_sof_timestamp = 0;
}

void cam_req_mgr_handle_core_shutdown(void)
@@ -609,6 +612,19 @@ static int __cam_req_mgr_check_link_is_ready(struct cam_req_mgr_core_link *link,
	traverse_data.validate_only = validate_only;
	traverse_data.open_req_cnt = link->open_req_cnt;

	/*
	 *  Some no-sync mode requests are processed after link config,
	 *  then process the sync mode requests after no-sync mode requests
	 *  are handled, the initial_skip should be false when processing
	 *  the sync mode requests.
	 */
	if (link->initial_skip) {
		CAM_DBG(CAM_CRM,
			"Set initial_skip to false for link %x",
			link->link_hdl);
		link->initial_skip = false;
	}

	/*
	 *  Traverse through all pd tables, if result is success,
	 *  apply the settings
@@ -897,6 +913,7 @@ static int __cam_req_mgr_check_sync_req_is_ready(
	int64_t 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;
	bool ready = true, sync_ready = true;

	if (!link->sync_link) {
@@ -912,6 +929,57 @@ static int __cam_req_mgr_check_sync_req_is_ready(
		"link_hdl %x req %lld frame_skip_flag %d ",
		link->link_hdl, req_id, link->sync_link_sof_skip);

	if (sync_link->initial_skip) {
		link->initial_skip = false;
		__cam_req_mgr_inject_delay(link->req.l_tbl, slot->idx);
		CAM_DBG(CAM_CRM,
			"sync link %x not streamed on",
			sync_link->link_hdl);
		return -EAGAIN;
	}

	if (sync_link->prev_sof_timestamp)
		sync_frame_duration = sync_link->sof_timestamp
			- sync_link->prev_sof_timestamp;
	else
		sync_frame_duration = DEFAULT_FRAME_DURATION;

	CAM_DBG(CAM_CRM,
		"sync link %x last frame_duration is %d ns",
		sync_link->link_hdl, sync_frame_duration);

	if (link->initial_skip) {
		link->initial_skip = false;

		if (link->sof_timestamp > sync_link->sof_timestamp &&
			sync_link->sof_timestamp > 0 &&
			link->sof_timestamp - sync_link->sof_timestamp <
			sync_frame_duration / 2) {
			/*
			 * If this frame sync with the previous frame of sync
			 * link, then we need to skip this frame, since the
			 * previous frame of sync link is also skipped.
			 */
			__cam_req_mgr_inject_delay(link->req.l_tbl, slot->idx);
			CAM_DBG(CAM_CRM,
				"This frame sync with previous sync_link %x frame",
				sync_link->link_hdl);
			return -EAGAIN;
		} else if (link->sof_timestamp <= sync_link->sof_timestamp) {
			/*
			 * Sometimes, link receives the SOF event is eariler
			 * than sync link in IFE CSID side, but link's SOF
			 * event is processed later than sync link's, then
			 * we need to skip this SOF event since the sync
			 * link's SOF event is also skipped.
			 */
			__cam_req_mgr_inject_delay(link->req.l_tbl, slot->idx);
			CAM_DBG(CAM_CRM,
				"The previous frame of sync link is skipped");
			return -EAGAIN;
		}
	}

	if (sync_link->sync_link_sof_skip) {
		CAM_DBG(CAM_REQ,
			"No req applied on corresponding SOF on sync link: %x",
@@ -1011,10 +1079,11 @@ static int __cam_req_mgr_check_sync_req_is_ready(
 *
 */
static int __cam_req_mgr_process_req(struct cam_req_mgr_core_link *link,
	uint32_t trigger)
	struct cam_req_mgr_trigger_notify *trigger_data)
{
	int                                  rc = 0, idx, last_app_idx;
	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;
@@ -1052,6 +1121,13 @@ static int __cam_req_mgr_process_req(struct cam_req_mgr_core_link *link,
	}

	if (trigger == CAM_TRIGGER_POINT_SOF) {
		/*
		 * Update the timestamp in session lock protection
		 * to avoid timing issue.
		 */
		link->prev_sof_timestamp = link->sof_timestamp;
		link->sof_timestamp = trigger_data->sof_timestamp_val;

		if (link->trigger_mask) {
			CAM_ERR_RATE_LIMIT(CAM_CRM,
				"Applying for last EOF fails");
@@ -2141,7 +2217,7 @@ static int cam_req_mgr_process_trigger(void *priv, void *data)
		__cam_req_mgr_inc_idx(&in_q->rd_idx, 1, in_q->num_slots);
	}

	rc = __cam_req_mgr_process_req(link, trigger_data->trigger);
	rc = __cam_req_mgr_process_req(link, trigger_data);

release_lock:
	mutex_unlock(&link->req.lock);
@@ -2372,6 +2448,7 @@ static int cam_req_mgr_cb_notify_trigger(
	notify_trigger->link_hdl = trigger_data->link_hdl;
	notify_trigger->dev_hdl = trigger_data->dev_hdl;
	notify_trigger->trigger = trigger_data->trigger;
	notify_trigger->sof_timestamp_val = trigger_data->sof_timestamp_val;
	task->process_cb = &cam_req_mgr_process_trigger;
	rc = cam_req_mgr_workq_enqueue_task(task, link, CRM_TASK_PRIORITY_0);

@@ -3125,8 +3202,6 @@ int cam_req_mgr_sync_config(

	link1->is_master = false;
	link2->is_master = false;
	link1->initial_skip = false;
	link2->initial_skip = false;

	link1->in_msync_mode = false;
	link2->in_msync_mode = false;
@@ -3137,6 +3212,16 @@ int cam_req_mgr_sync_config(
		link1->sync_link = link2;
		link2->sync_link = link1;
		__cam_req_mgr_set_master_link(link1, link2);
	} 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;
	}

	cam_session->sync_mode = sync_info->sync_mode;
+9 −1
Original line number Diff line number Diff line
@@ -32,6 +32,9 @@

#define MAX_SYNC_COUNT 65535

/* Default frame rate is 30 */
#define DEFAULT_FRAME_DURATION 33333333

#define SYNC_LINK_SOF_CNT_MAX_LMT 1

#define MAXIMUM_LINKS_PER_SESSION  4
@@ -321,7 +324,10 @@ struct cam_req_mgr_connected_device {
 *                         master-slave sync
 * @in_msync_mode        : Flag to determine if a link is in master-slave mode
 * @initial_sync_req     : The initial req which is required to sync with the
 *                         other link
 *                         other link, it means current hasn't receive any
 *                         stream after streamon if it is true
 * @sof_timestamp_value  : SOF timestamp value
 * @prev_sof_timestamp   : Previous SOF timestamp value
 */
struct cam_req_mgr_core_link {
	int32_t                              link_hdl;
@@ -348,6 +354,8 @@ struct cam_req_mgr_core_link {
	bool                                 initial_skip;
	bool                                 in_msync_mode;
	int64_t                              initial_sync_req;
	uint64_t                             sof_timestamp;
	uint64_t                             prev_sof_timestamp;
};

/**
+3 −1
Original line number Diff line number Diff line
/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
/* Copyright (c) 2016-2019, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -201,12 +201,14 @@ enum cam_req_mgr_link_evt_type {
 * @frame_id : frame id for internal tracking
 * @trigger  : trigger point of this notification, CRM will send apply
 * only to the devices which subscribe to this point.
 * @sof_timestamp_val: Captured time stamp value at sof hw event
 */
struct cam_req_mgr_trigger_notify {
	int32_t  link_hdl;
	int32_t  dev_hdl;
	int64_t  frame_id;
	uint32_t trigger;
	uint64_t sof_timestamp_val;
};

/**