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

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

Merge "msm: camera: reqmgr: Adds total ordering of reqs for all pd devices" into dev/msm-4.9-camx

parents bbd59a1f ef0cd84c
Loading
Loading
Loading
Loading
+116 −43
Original line number Diff line number Diff line
@@ -25,23 +25,6 @@

static struct cam_req_mgr_core_device *g_crm_core_dev;


void cam_req_mgr_handle_core_shutdown(void)
{
	struct cam_req_mgr_core_session *session;
	struct cam_req_mgr_core_session *tsession;
	struct cam_req_mgr_session_info ses_info;

	if (!list_empty(&g_crm_core_dev->session_head)) {
		list_for_each_entry_safe(session, tsession,
			&g_crm_core_dev->session_head, entry) {
			ses_info.session_hdl =
				session->session_hdl;
			cam_req_mgr_destroy_session(&ses_info);
		}
	}
}

static int __cam_req_mgr_setup_payload(struct cam_req_mgr_core_workq *workq)
{
	int32_t                  i = 0;
@@ -202,11 +185,18 @@ static int __cam_req_mgr_traverse(struct cam_req_mgr_traverse *traverse_data)

	if (tbl->inject_delay > 0 && (traverse_data->validate_only == false)) {
		CAM_DBG(CAM_CRM, "Injecting Delay of one frame");
		apply_data[tbl->pd].req_id = -1;
		tbl->inject_delay--;
		/* This pd table is not ready to proceed with asked idx */
		SET_FAILURE_BIT(traverse_data->result, tbl->pd);
		return -EAGAIN;
		apply_data[tbl->pd].req_id = -1;
		if (tbl->next) {
			__cam_req_mgr_dec_idx(&next_idx, tbl->pd_delta,
				tbl->num_slots);
			traverse_data->idx = next_idx;
			traverse_data->tbl = tbl->next;
			rc = __cam_req_mgr_traverse(traverse_data);
		}
		return rc;
	}

	/* Check if req is ready or in skip mode or pd tbl is in skip mode */
@@ -241,8 +231,20 @@ static int __cam_req_mgr_traverse(struct cam_req_mgr_traverse *traverse_data)
		}
	} else {
		/* This pd table is not ready to proceed with asked idx */
		if (tbl->slot[curr_idx].state == CRM_REQ_STATE_APPLIED)
			SET_SUCCESS_BIT(traverse_data->result, tbl->pd);
		else
			SET_FAILURE_BIT(traverse_data->result, tbl->pd);
		return -EAGAIN;

		apply_data[tbl->pd].req_id = -1;
		if (tbl->next) {
			__cam_req_mgr_dec_idx(&next_idx, tbl->pd_delta,
				tbl->num_slots);
			traverse_data->idx = next_idx;
			traverse_data->tbl = tbl->next;
			rc = __cam_req_mgr_traverse(traverse_data);
		}
		return rc;
	}
	return 0;
}
@@ -472,12 +474,14 @@ static int __cam_req_mgr_send_req(struct cam_req_mgr_core_link *link,
 *                  traversed through
 * @idx           : index within input request queue
 * @validate_only : Whether to validate only and/or update settings
 * @result        : Holds the value that indicates which of the pd
 *                  tables have a req that is ready to be applied
 *
 * @return   : 0 for success, negative for failure
 *
 */
static int __cam_req_mgr_check_link_is_ready(struct cam_req_mgr_core_link *link,
	int32_t idx, bool validate_only)
	int32_t idx, bool validate_only, int *result)
{
	int                            rc;
	struct cam_req_mgr_traverse    traverse_data;
@@ -508,15 +512,18 @@ static int __cam_req_mgr_check_link_is_ready(struct cam_req_mgr_core_link *link,
	CAM_DBG(CAM_CRM, "SOF: idx %d result %x pd_mask %x rc %d",
		idx, traverse_data.result, link->pd_mask, rc);

	if (!rc && traverse_data.result == link->pd_mask) {
	if (!traverse_data.result)
		return -EAGAIN;

	if (!rc) {
		CAM_DBG(CAM_CRM,
			"APPLY: link_hdl= %x idx= %d, req_id= %lld :%lld :%lld",
			link->link_hdl, idx,
			apply_data[2].req_id, apply_data[1].req_id,
			apply_data[0].req_id);
	} else
		rc = -EAGAIN;
	}

	*result = traverse_data.result;
	return rc;
}

@@ -645,12 +652,16 @@ static int __cam_req_mgr_validate_sof_cnt(
 * @link     : pointer to link whose input queue and req tbl are
 *             traversed through
 * @slot     : pointer to the current slot being processed
 * @result   : Holds the value that indicates which of the pd
 *             tables have a req that is ready to be applied
 *
 * @return   : 0 for success, negative for failure
 *
 */
static int __cam_req_mgr_process_sync_req(
	struct cam_req_mgr_core_link *link,
	struct cam_req_mgr_slot *slot)
	struct cam_req_mgr_slot *slot,
	int *result)
{
	struct cam_req_mgr_core_link *sync_link = NULL;
	int64_t req_id = 0;
@@ -675,7 +686,7 @@ static int __cam_req_mgr_process_sync_req(
		link->sof_counter++;
	}

	rc = __cam_req_mgr_check_link_is_ready(link, slot->idx, true);
	rc = __cam_req_mgr_check_link_is_ready(link, slot->idx, true, result);
	if (rc) {
		CAM_DBG(CAM_CRM,
			"Req: %lld [My link]not available link: %x, rc=%d",
@@ -687,7 +698,7 @@ static int __cam_req_mgr_process_sync_req(
		sync_link->req.in_q, req_id);
	if (sync_slot_idx != -1) {
		rc = __cam_req_mgr_check_link_is_ready(
			sync_link, sync_slot_idx, true);
			sync_link, sync_slot_idx, true, result);
		CAM_DBG(CAM_CRM, "sync_slot_idx=%d, status=%d, rc=%d",
			sync_slot_idx,
			sync_link->req.in_q->slot[sync_slot_idx].status,
@@ -707,7 +718,8 @@ static int __cam_req_mgr_process_sync_req(
				req_id, sync_link->link_hdl);
			goto failure;
		}
		__cam_req_mgr_check_link_is_ready(link, slot->idx, false);
		__cam_req_mgr_check_link_is_ready(link, slot->idx, false,
			result);
	} else {
		CAM_DBG(CAM_CRM,
			"Req: %lld [Other link] not ready to apply on link: %x",
@@ -723,6 +735,41 @@ static int __cam_req_mgr_process_sync_req(
	return rc;
}

/**
 * __cam_req_mgr_reset_pd_tables()
 *
 * @brief    : resets pd tables based on req getting applied on
 *             from a particular pd table
 * @link     : pointer to link whose input queue and req tbl are
 *             traversed through
 * @slot     : Pointer to the current slot
 * @result   : indicates request of which pd table was successfully
 *             processed
 *
 */
static void __cam_req_mgr_reset_pd_tables(
	struct cam_req_mgr_core_link *link,
	struct cam_req_mgr_slot *slot,
	int result)
{
	int pd_set_bit = 0;
	int curr_idx = slot->idx;
	int no_tables = link->req.num_tbl;
	int max_pd_delay = link->max_delay;
	struct cam_req_mgr_req_tbl  *tbl = link->req.l_tbl;
	struct cam_req_mgr_req_queue *in_q = link->req.in_q;

	while (no_tables) {
		pd_set_bit = (result & (1 << max_pd_delay));
		if (pd_set_bit)
			tbl->slot[curr_idx].state = CRM_REQ_STATE_APPLIED;
		max_pd_delay--;
		no_tables--;
		tbl = tbl->next;
		__cam_req_mgr_dec_idx(&curr_idx, 1, in_q->num_slots);
	}
}

/**
 * __cam_req_mgr_process_req()
 *
@@ -736,7 +783,7 @@ static int __cam_req_mgr_process_sync_req(
static int __cam_req_mgr_process_req(struct cam_req_mgr_core_link *link,
	uint32_t trigger)
{
	int                                  rc = 0, idx;
	int                                  rc = 0, idx, result = 0;
	struct cam_req_mgr_slot             *slot = NULL;
	struct cam_req_mgr_req_queue        *in_q;
	struct cam_req_mgr_core_session     *session;
@@ -782,10 +829,11 @@ static int __cam_req_mgr_process_req(struct cam_req_mgr_core_link *link,
		}

		if (slot->sync_mode == CAM_REQ_MGR_SYNC_MODE_SYNC)
			rc = __cam_req_mgr_process_sync_req(link, slot);
			rc = __cam_req_mgr_process_sync_req(link, slot,
				&result);
		else
			rc = __cam_req_mgr_check_link_is_ready(link,
				slot->idx, false);
				slot->idx, false, &result);

		if (rc < 0) {
			/*
@@ -830,16 +878,25 @@ static int __cam_req_mgr_process_req(struct cam_req_mgr_core_link *link,
		spin_unlock_bh(&link->link_state_spin_lock);

		if (link->trigger_mask == link->subscribe_event) {
			if (result == link->pd_mask) {
				slot->status = CRM_SLOT_STATUS_REQ_APPLIED;
			link->trigger_mask = 0;
				CAM_DBG(CAM_CRM, "req %d is applied on link %d",
				slot->req_id,
				link->link_hdl);
					slot->req_id, link->link_hdl);
				idx = in_q->rd_idx;
				__cam_req_mgr_dec_idx(
					&idx, link->max_delay + 1,
					in_q->num_slots);
				__cam_req_mgr_reset_req_slot(link, idx);
			} else {
				CAM_DBG(CAM_CRM,
					"Req:%lld not applied on all devices",
				slot->req_id);
				__cam_req_mgr_reset_pd_tables(link, slot,
					result);
				slot->status = CRM_SLOT_STATUS_REQ_PENDING;
			}

			link->trigger_mask = 0;
		}
	}
	mutex_unlock(&session->lock);
@@ -2028,6 +2085,22 @@ static int __cam_req_mgr_setup_link_info(struct cam_req_mgr_core_link *link,
	return rc;
}

void cam_req_mgr_handle_core_shutdown(void)
{
	struct cam_req_mgr_core_session *session;
	struct cam_req_mgr_core_session *tsession;
	struct cam_req_mgr_session_info ses_info;

	if (!list_empty(&g_crm_core_dev->session_head)) {
		list_for_each_entry_safe(session, tsession,
			&g_crm_core_dev->session_head, entry) {
			ses_info.session_hdl =
				session->session_hdl;
			cam_req_mgr_destroy_session(&ses_info);
		}
	}
}

/* IOCTLs handling section */
int cam_req_mgr_create_session(
	struct cam_req_mgr_session_info *ses_info)
+2 −0
Original line number Diff line number Diff line
@@ -79,12 +79,14 @@ struct crm_task_payload {
 * EMPTY   : indicates req slot is empty
 * PENDING : indicates req slot is waiting for reqs from all devs
 * READY   : indicates req slot is ready to be sent to devs
 * APPLIED : indicates req slot is already sent to devs
 * INVALID : indicates req slot is not in valid state
 */
enum crm_req_state {
	CRM_REQ_STATE_EMPTY,
	CRM_REQ_STATE_PENDING,
	CRM_REQ_STATE_READY,
	CRM_REQ_STATE_APPLIED,
	CRM_REQ_STATE_INVALID,
};