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

Commit 65a86de9 authored by Ayush Kumar's avatar Ayush Kumar
Browse files

msm: camera: req_mgr: Re-design CRM to support multi links in sync mode



This change is to support multi links in sync mode. Supports dynmanic
switching to select master link in rtb and sat use case in sync mode.
Supports sync logic for rtb and sat use case in sync mode. Apply
requests for all links is triggered only on master epoch.
Supports bubble recovery and sync logic for different pd links in
sync mode.

CRs-Fixed: 2783209
Change-Id: I81d1d0d37aa0d6e18c19ca87eac51ef3f160abfb
Signed-off-by: default avatarAyush Kumar <ayushkr@codeaurora.org>
parent 3476bc16
Loading
Loading
Loading
Loading
+28 −1
Original line number Original line Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
// SPDX-License-Identifier: GPL-2.0-only
/*
/*
 * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
 * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
 */
 */


#include <linux/slab.h>
#include <linux/slab.h>
@@ -182,6 +182,33 @@ int cam_context_handle_crm_apply_req(struct cam_context *ctx,
	return rc;
	return rc;
}
}


int cam_context_handle_crm_state_change(struct cam_context *ctx,
	struct cam_req_mgr_request_change_state *state_info)
{
	int rc;

	if (!ctx->state_machine) {
		CAM_ERR(CAM_CORE, "Context is not ready");
		return -EINVAL;
	}

	if (!state_info) {
		CAM_ERR(CAM_CORE, "Invalid change state payload");
		return -EINVAL;
	}

	if (ctx->state_machine[ctx->state].crm_ops.change_state) {
		rc = ctx->state_machine[ctx->state].crm_ops.change_state(ctx,
			state_info);
	} else {
		CAM_ERR(CAM_CORE, "No crm change state req in dev %d, state %d",
			ctx->dev_hdl, ctx->state);
		rc = -EPROTO;
	}

	return rc;
}

int cam_context_handle_crm_notify_frame_skip(
int cam_context_handle_crm_notify_frame_skip(
	struct cam_context *ctx,
	struct cam_context *ctx,
	struct cam_req_mgr_apply_request *apply)
	struct cam_req_mgr_apply_request *apply)
+16 −1
Original line number Original line Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0-only */
/* SPDX-License-Identifier: GPL-2.0-only */
/*
/*
 * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
 * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
 */
 */


#ifndef _CAM_CONTEXT_H_
#ifndef _CAM_CONTEXT_H_
@@ -127,6 +127,7 @@ struct cam_ctx_ioctl_ops {
 * @flush_req:             Flush request to remove request ids
 * @flush_req:             Flush request to remove request ids
 * @process_evt:           Handle event notification from CRM.(optional)
 * @process_evt:           Handle event notification from CRM.(optional)
 * @dump_req:              Dump information for the issue request
 * @dump_req:              Dump information for the issue request
 * @change_state:          Change sub-state of hw context layer to bubble
 *
 *
 */
 */
struct cam_ctx_crm_ops {
struct cam_ctx_crm_ops {
@@ -146,6 +147,8 @@ struct cam_ctx_crm_ops {
			struct cam_req_mgr_link_evt_data *evt_data);
			struct cam_req_mgr_link_evt_data *evt_data);
	int (*dump_req)(struct cam_context *ctx,
	int (*dump_req)(struct cam_context *ctx,
			struct cam_req_mgr_dump_info *dump);
			struct cam_req_mgr_dump_info *dump);
	int (*change_state)(struct cam_context *ctx,
			struct cam_req_mgr_request_change_state *change_state);
};
};




@@ -310,6 +313,18 @@ int cam_context_handle_crm_unlink(struct cam_context *ctx,
int cam_context_handle_crm_apply_req(struct cam_context *ctx,
int cam_context_handle_crm_apply_req(struct cam_context *ctx,
		struct cam_req_mgr_apply_request *apply);
		struct cam_req_mgr_apply_request *apply);


/**
 * cam_context_handle_crm_state_change()
 *
 * @brief:        Handle state change request
 *
 * @ctx:          Object pointer for cam_context
 * @state_info:   State change request command payload
 *
 */
int cam_context_handle_crm_state_change(struct cam_context *ctx,
		struct cam_req_mgr_request_change_state *state_info);

/**
/**
 * cam_context_handle_crm_notify_frame_skip()
 * cam_context_handle_crm_notify_frame_skip()
 *
 *
+20 −1
Original line number Original line Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
// SPDX-License-Identifier: GPL-2.0-only
/*
/*
 * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
 * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
 */
 */


#include <linux/debugfs.h>
#include <linux/debugfs.h>
@@ -619,6 +619,24 @@ static int __cam_node_crm_flush_req(struct cam_req_mgr_flush_request *flush)
	return cam_context_handle_crm_flush_req(ctx, flush);
	return cam_context_handle_crm_flush_req(ctx, flush);
}
}


static int __cam_node_crm_state_change_req(
	struct cam_req_mgr_request_change_state *state_info)
{
	struct cam_context *ctx = NULL;

	if (!state_info)
		return -EINVAL;

	ctx = (struct cam_context *) cam_get_device_priv(state_info->dev_hdl);
	if (!ctx) {
		CAM_ERR(CAM_CORE, "Can not get context for handle %d",
			state_info->dev_hdl);
		return -EINVAL;
	}

	return cam_context_handle_crm_state_change(ctx, state_info);
}

static int __cam_node_crm_process_evt(
static int __cam_node_crm_process_evt(
	struct cam_req_mgr_link_evt_data *evt_data)
	struct cam_req_mgr_link_evt_data *evt_data)
{
{
@@ -715,6 +733,7 @@ int cam_node_init(struct cam_node *node, struct cam_hw_mgr_intf *hw_mgr_intf,
	node->crm_node_intf.dump_req = __cam_node_crm_dump_req;
	node->crm_node_intf.dump_req = __cam_node_crm_dump_req;
	node->crm_node_intf.notify_frame_skip =
	node->crm_node_intf.notify_frame_skip =
		__cam_node_crm_notify_frame_skip;
		__cam_node_crm_notify_frame_skip;
	node->crm_node_intf.change_state = __cam_node_crm_state_change_req;


	mutex_init(&node->list_mutex);
	mutex_init(&node->list_mutex);
	INIT_LIST_HEAD(&node->free_ctx_list);
	INIT_LIST_HEAD(&node->free_ctx_list);
+1 −0
Original line number Original line Diff line number Diff line
@@ -549,6 +549,7 @@ static int __cam_custom_ctx_get_dev_info_in_acquired(struct cam_context *ctx,
	dev_info->dev_id = CAM_REQ_MGR_DEVICE_CUSTOM_HW;
	dev_info->dev_id = CAM_REQ_MGR_DEVICE_CUSTOM_HW;
	dev_info->p_delay = 1;
	dev_info->p_delay = 1;
	dev_info->trigger = CAM_TRIGGER_POINT_SOF;
	dev_info->trigger = CAM_TRIGGER_POINT_SOF;
	dev_info->sof_ts_cb = NULL;


	return 0;
	return 0;
}
}
+186 −16
Original line number Original line Diff line number Diff line
@@ -743,8 +743,8 @@ static void __cam_isp_ctx_send_sof_timestamp(
	req_msg.u.frame_msg.frame_id_meta = ctx_isp->frame_id_meta;
	req_msg.u.frame_msg.frame_id_meta = ctx_isp->frame_id_meta;


	CAM_DBG(CAM_ISP,
	CAM_DBG(CAM_ISP,
		"request id:%lld frame number:%lld SOF time stamp:0x%llx status:%u",
		"link hdl 0x%x request id:%lld frame number:%lld SOF time stamp:%lld status:%u",
		 request_id, ctx_isp->frame_id,
		ctx_isp->base->link_hdl, request_id, ctx_isp->frame_id,
		ctx_isp->sof_timestamp_val, sof_event_status);
		ctx_isp->sof_timestamp_val, sof_event_status);


	if (cam_req_mgr_notify_message(&req_msg,
	if (cam_req_mgr_notify_message(&req_msg,
@@ -1671,6 +1671,7 @@ static int __cam_isp_ctx_reg_upd_in_applied_state(
	}
	}
	req = list_first_entry(&ctx->wait_req_list,
	req = list_first_entry(&ctx->wait_req_list,
			struct cam_ctx_request, list);
			struct cam_ctx_request, list);

	list_del_init(&req->list);
	list_del_init(&req->list);


	req_isp = (struct cam_isp_ctx_req *) req->req_priv;
	req_isp = (struct cam_isp_ctx_req *) req->req_priv;
@@ -1679,8 +1680,9 @@ static int __cam_isp_ctx_reg_upd_in_applied_state(
		ctx_isp->active_req_cnt++;
		ctx_isp->active_req_cnt++;
		request_id = req->request_id;
		request_id = req->request_id;
		CAM_DBG(CAM_REQ,
		CAM_DBG(CAM_REQ,
			"move request %lld to active list(cnt = %d), ctx %u",
			"move request %lld to active list(cnt = %d), ctx %u link %x",
			req->request_id, ctx_isp->active_req_cnt, ctx->ctx_id);
			req->request_id, ctx_isp->active_req_cnt,
			ctx->ctx_id, ctx->link_hdl);
		__cam_isp_ctx_update_event_record(ctx_isp,
		__cam_isp_ctx_update_event_record(ctx_isp,
			CAM_ISP_CTX_EVENT_RUP, req);
			CAM_ISP_CTX_EVENT_RUP, req);
	} else {
	} else {
@@ -1822,6 +1824,7 @@ static int __cam_isp_ctx_notify_sof_in_activated_state(
			notify.trigger = CAM_TRIGGER_POINT_SOF;
			notify.trigger = CAM_TRIGGER_POINT_SOF;
			notify.req_id = ctx_isp->req_info.last_bufdone_req_id;
			notify.req_id = ctx_isp->req_info.last_bufdone_req_id;
			notify.sof_timestamp_val = ctx_isp->sof_timestamp_val;
			notify.sof_timestamp_val = ctx_isp->sof_timestamp_val;
			notify.sof_boottime = ctx_isp->boot_timestamp;
			notify.trigger_id = ctx_isp->trigger_id;
			notify.trigger_id = ctx_isp->trigger_id;


			ctx->ctx_crm_intf->notify_trigger(&notify);
			ctx->ctx_crm_intf->notify_trigger(&notify);
@@ -1941,8 +1944,9 @@ static int __cam_isp_ctx_sof_in_activated_state(
	__cam_isp_ctx_update_state_monitor_array(ctx_isp,
	__cam_isp_ctx_update_state_monitor_array(ctx_isp,
		CAM_ISP_STATE_CHANGE_TRIGGER_SOF, request_id);
		CAM_ISP_STATE_CHANGE_TRIGGER_SOF, request_id);


	CAM_DBG(CAM_ISP, "frame id: %lld time stamp:0x%llx, ctx %u",
	CAM_DBG(CAM_ISP, "frame id: %lld time stamp:0x%llx, ctx %u link %x",
		ctx_isp->frame_id, ctx_isp->sof_timestamp_val, ctx->ctx_id);
		ctx_isp->frame_id, ctx_isp->sof_timestamp_val,
		ctx->ctx_id, ctx->link_hdl);


	return rc;
	return rc;
}
}
@@ -1987,6 +1991,7 @@ static int __cam_isp_ctx_reg_upd_in_sof(struct cam_isp_context *ctx_isp,
static int __cam_isp_ctx_epoch_in_applied(struct cam_isp_context *ctx_isp,
static int __cam_isp_ctx_epoch_in_applied(struct cam_isp_context *ctx_isp,
	void *evt_data)
	void *evt_data)
{
{
	bool rc = false;
	uint64_t request_id = 0;
	uint64_t request_id = 0;
	struct cam_req_mgr_trigger_notify   notify;
	struct cam_req_mgr_trigger_notify   notify;
	struct cam_ctx_request             *req;
	struct cam_ctx_request             *req;
@@ -2024,8 +2029,9 @@ static int __cam_isp_ctx_epoch_in_applied(struct cam_isp_context *ctx_isp,
	req_isp->reapply = true;
	req_isp->reapply = true;
	req_isp->cdm_reset_before_apply = false;
	req_isp->cdm_reset_before_apply = false;


	CAM_INFO_RATE_LIMIT(CAM_ISP, "ctx:%d Report Bubble flag %d req id:%lld",
	CAM_INFO_RATE_LIMIT(CAM_ISP, "ctx:%d link %x  Report Bubble flag %d req id:%lld",
		ctx->ctx_id, req_isp->bubble_report, req->request_id);
		ctx->ctx_id, ctx->link_hdl,
		req_isp->bubble_report, req->request_id);
	if (req_isp->bubble_report && ctx->ctx_crm_intf &&
	if (req_isp->bubble_report && ctx->ctx_crm_intf &&
		ctx->ctx_crm_intf->notify_err) {
		ctx->ctx_crm_intf->notify_err) {
		struct cam_req_mgr_error_notify notify;
		struct cam_req_mgr_error_notify notify;
@@ -2039,12 +2045,25 @@ static int __cam_isp_ctx_epoch_in_applied(struct cam_isp_context *ctx_isp,
			notify.trigger = CAM_TRIGGER_POINT_SOF;
			notify.trigger = CAM_TRIGGER_POINT_SOF;
		notify.frame_id = ctx_isp->frame_id;
		notify.frame_id = ctx_isp->frame_id;
		notify.sof_timestamp_val = ctx_isp->sof_timestamp_val;
		notify.sof_timestamp_val = ctx_isp->sof_timestamp_val;
		notify.sof_boottime_val = ctx_isp->boot_timestamp;
		notify.need_recovery = true;
		CAM_WARN_RATE_LIMIT(CAM_ISP,
		CAM_WARN_RATE_LIMIT(CAM_ISP,
			"Notify CRM about Bubble req %lld frame %lld, ctx %u",
			"Notify CRM about Bubble req %lld frame %lld, ctx %u",
			req->request_id, ctx_isp->frame_id, ctx->ctx_id);
			req->request_id, ctx_isp->frame_id, ctx->ctx_id);
		trace_cam_log_event("Bubble", "Rcvd epoch in applied state",
		trace_cam_log_event("Bubble", "Rcvd epoch in applied state",
			req->request_id, ctx->ctx_id);
			req->request_id, ctx->ctx_id);
		ctx->ctx_crm_intf->notify_err(&notify);
		rc = ctx->ctx_crm_intf->notify_err(&notify);

		CAM_DBG(CAM_CRM, "Need bubble recovery %d", rc);

		if (rc) {
			req_isp->bubble_detected = false;
			req_isp->reapply = false;
			CAM_DBG(CAM_ISP, "Disable bubble for ctx %d link %d",
				ctx->ctx_id, ctx->link_hdl);
			return 0;
		}

		atomic_set(&ctx_isp->process_bubble, 1);
		atomic_set(&ctx_isp->process_bubble, 1);
	} else {
	} else {
		req_isp->bubble_report = 0;
		req_isp->bubble_report = 0;
@@ -2198,6 +2217,7 @@ static int __cam_isp_ctx_buf_done_in_bubble(
static int __cam_isp_ctx_epoch_in_bubble_applied(
static int __cam_isp_ctx_epoch_in_bubble_applied(
	struct cam_isp_context *ctx_isp, void *evt_data)
	struct cam_isp_context *ctx_isp, void *evt_data)
{
{
	int rc = 0;
	uint64_t  request_id = 0;
	uint64_t  request_id = 0;
	struct cam_req_mgr_trigger_notify   notify;
	struct cam_req_mgr_trigger_notify   notify;
	struct cam_ctx_request             *req;
	struct cam_ctx_request             *req;
@@ -2255,10 +2275,17 @@ static int __cam_isp_ctx_epoch_in_bubble_applied(
			notify.trigger = CAM_TRIGGER_POINT_SOF;
			notify.trigger = CAM_TRIGGER_POINT_SOF;
		notify.frame_id = ctx_isp->frame_id;
		notify.frame_id = ctx_isp->frame_id;
		notify.sof_timestamp_val = ctx_isp->sof_timestamp_val;
		notify.sof_timestamp_val = ctx_isp->sof_timestamp_val;
		notify.sof_boottime_val = ctx_isp->boot_timestamp;
		notify.need_recovery = true;
		CAM_WARN_RATE_LIMIT(CAM_REQ,
		CAM_WARN_RATE_LIMIT(CAM_REQ,
			"Notify CRM about Bubble req_id %llu frame %lld, ctx %u",
			"Notify CRM about Bubble req_id %llu frame %lld, ctx %u",
			req->request_id, ctx_isp->frame_id, ctx->ctx_id);
			req->request_id, ctx_isp->frame_id, ctx->ctx_id);
		ctx->ctx_crm_intf->notify_err(&notify);
		rc = ctx->ctx_crm_intf->notify_err(&notify);
		if (rc) {
			req_isp->bubble_detected = false;
			req_isp->reapply = false;
			return 0;
		}
		atomic_set(&ctx_isp->process_bubble, 1);
		atomic_set(&ctx_isp->process_bubble, 1);
	} else {
	} else {
		req_isp->bubble_report = 0;
		req_isp->bubble_report = 0;
@@ -3122,10 +3149,10 @@ static int __cam_isp_ctx_apply_req_in_activated_state(
		goto end;
		goto end;
	}
	}


	CAM_DBG(CAM_REQ, "Apply request %lld in Substate[%s] ctx %u",
	CAM_DBG(CAM_REQ, "Apply request %lld in Substate[%s] ctx %u link %x",
		req->request_id,
		req->request_id,
		__cam_isp_ctx_substate_val_to_type(ctx_isp->substate_activated),
		__cam_isp_ctx_substate_val_to_type(ctx_isp->substate_activated),
		ctx->ctx_id);
		ctx->ctx_id, ctx->link_hdl);
	req_isp = (struct cam_isp_ctx_req *) req->req_priv;
	req_isp = (struct cam_isp_ctx_req *) req->req_priv;


	if (ctx_isp->active_req_cnt >=  2) {
	if (ctx_isp->active_req_cnt >=  2) {
@@ -3208,6 +3235,81 @@ static int __cam_isp_ctx_apply_req_in_activated_state(
	return rc;
	return rc;
}
}


static int __cam_isp_ctx_change_substate(
	struct cam_context *ctx,
	struct cam_req_mgr_request_change_state *state_info)
{
	int                        rc = 0;
	uint64_t                   request_id = 0;
	struct cam_ctx_request    *req = NULL;
	struct cam_ctx_request    *req_temp = NULL;
	struct cam_ctx_request    *bubble_req = NULL;
	struct cam_isp_ctx_req    *req_isp = NULL;
	struct cam_isp_context    *ctx_isp =
				    (struct cam_isp_context *) ctx->ctx_priv;

	if (!list_empty(&ctx->wait_req_list)) {
		req = list_first_entry(&ctx->wait_req_list,
			struct cam_ctx_request,
			list);
		if (req->request_id == state_info->req_id) {
			req_isp = (struct cam_isp_ctx_req *)req->req_priv;
			req_isp->bubble_detected = true;
			req_isp->reapply = true;
			bubble_req = req;
			list_del_init(&req->list);
			list_add_tail(&req->list, &ctx->active_req_list);
			goto end;
		}
	} else {
		CAM_ERR(CAM_ISP, "Ctx:%d No wait request", ctx->ctx_id);
	}

	if (!bubble_req) {
		list_for_each_entry_safe(req, req_temp,
			&ctx->active_req_list, list) {
			if (req->request_id == state_info->req_id) {
				req_isp =
					(struct cam_isp_ctx_req *)req->req_priv;
				req_isp->bubble_detected = true;
				req_isp->reapply = true;
				bubble_req = req;
				break;
			}
		}
	}

	if (!bubble_req) {
		CAM_ERR(CAM_ISP, "Req %lld not in active list ctx : %d",
			state_info->req_id,
			ctx->ctx_id);
		goto done;
	}

end:

	if (req_isp->bubble_report)
		atomic_set(&ctx_isp->process_bubble, 1);

	if ((req->request_id > ctx_isp->reported_req_id)
		&& !req_isp->bubble_report) {
		request_id = req->request_id;
		ctx_isp->reported_req_id = request_id;
	}

	__cam_isp_ctx_send_sof_timestamp(ctx_isp, request_id,
		CAM_REQ_MGR_SOF_EVENT_ERROR);

	ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_BUBBLE;

	CAM_DBG(CAM_ISP, "next Substate[%s] ctx : %d",
		__cam_isp_ctx_substate_val_to_type(
		ctx_isp->substate_activated), ctx->ctx_id);

done:
	return rc;
}

static int __cam_isp_ctx_apply_req_in_sof(
static int __cam_isp_ctx_apply_req_in_sof(
	struct cam_context *ctx, struct cam_req_mgr_apply_request *apply)
	struct cam_context *ctx, struct cam_req_mgr_apply_request *apply)
{
{
@@ -3268,8 +3370,8 @@ static int __cam_isp_ctx_apply_req_in_bubble(
		ctx_isp->substate_activated));
		ctx_isp->substate_activated));
	rc = __cam_isp_ctx_apply_req_in_activated_state(ctx, apply,
	rc = __cam_isp_ctx_apply_req_in_activated_state(ctx, apply,
		CAM_ISP_CTX_ACTIVATED_BUBBLE_APPLIED);
		CAM_ISP_CTX_ACTIVATED_BUBBLE_APPLIED);
	CAM_DBG(CAM_ISP, "new Substate[%s]",
	CAM_DBG(CAM_ISP, "ctx %d link %x new Substate[%s]",
		__cam_isp_ctx_substate_val_to_type(
		ctx->ctx_id, ctx->link_hdl, __cam_isp_ctx_substate_val_to_type(
		ctx_isp->substate_activated));
		ctx_isp->substate_activated));


	if (rc)
	if (rc)
@@ -3633,6 +3735,7 @@ static int __cam_isp_ctx_flush_req_in_top_state(
				flush_req);
				flush_req);


		ctx_isp->active_req_cnt = 0;
		ctx_isp->active_req_cnt = 0;

		spin_unlock_bh(&ctx->lock);
		spin_unlock_bh(&ctx->lock);


		reset_args.ctxt_to_hw_map = ctx_isp->hw_ctx;
		reset_args.ctxt_to_hw_map = ctx_isp->hw_ctx;
@@ -3680,13 +3783,16 @@ static struct cam_ctx_ops
		.ioctl_ops = {},
		.ioctl_ops = {},
		.crm_ops = {
		.crm_ops = {
			.apply_req = __cam_isp_ctx_apply_req_in_sof,
			.apply_req = __cam_isp_ctx_apply_req_in_sof,
			.change_state = __cam_isp_ctx_change_substate,
		},
		},
		.irq_ops = NULL,
		.irq_ops = NULL,
	},
	},
	/* APPLIED */
	/* APPLIED */
	{
	{
		.ioctl_ops = {},
		.ioctl_ops = {},
		.crm_ops = {},
		.crm_ops = {
			.change_state = __cam_isp_ctx_change_substate,
		},
		.irq_ops = NULL,
		.irq_ops = NULL,
	},
	},
	/* EPOCH */
	/* EPOCH */
@@ -3694,6 +3800,7 @@ static struct cam_ctx_ops
		.ioctl_ops = {},
		.ioctl_ops = {},
		.crm_ops = {
		.crm_ops = {
			.apply_req = __cam_isp_ctx_apply_req_in_epoch,
			.apply_req = __cam_isp_ctx_apply_req_in_epoch,
			.change_state = __cam_isp_ctx_change_substate,
		},
		},
		.irq_ops = NULL,
		.irq_ops = NULL,
	},
	},
@@ -3702,13 +3809,16 @@ static struct cam_ctx_ops
		.ioctl_ops = {},
		.ioctl_ops = {},
		.crm_ops = {
		.crm_ops = {
			.apply_req = __cam_isp_ctx_apply_req_in_bubble,
			.apply_req = __cam_isp_ctx_apply_req_in_bubble,
			.change_state = __cam_isp_ctx_change_substate,
		},
		},
		.irq_ops = NULL,
		.irq_ops = NULL,
	},
	},
	/* Bubble Applied */
	/* Bubble Applied */
	{
	{
		.ioctl_ops = {},
		.ioctl_ops = {},
		.crm_ops = {},
		.crm_ops = {
			.change_state = __cam_isp_ctx_change_substate,
		},
		.irq_ops = NULL,
		.irq_ops = NULL,
	},
	},
	/* HW ERROR */
	/* HW ERROR */
@@ -5227,6 +5337,33 @@ static int __cam_isp_ctx_unlink_in_acquired(struct cam_context *ctx,
	return rc;
	return rc;
}
}


static int __cam_isp_ctx_get_isp_info(int32_t dev_hdl, void *data)
{
	int rc = 0;
	struct cam_context               *ctx;
	struct cam_req_mgr_dev_info      *isp_dev = data;
	struct cam_isp_context           *isp_ctx = NULL;

	ctx = (struct cam_context *)cam_get_device_priv(dev_hdl);

	isp_ctx = (struct cam_isp_context *)ctx->ctx_priv;

	isp_dev->state = isp_ctx->substate_activated;
	isp_dev->timestamp = isp_ctx->sof_timestamp_val;
	isp_dev->boot_time = isp_ctx->boot_timestamp;
	isp_dev->frame_id = isp_ctx->frame_id;

	if ((isp_ctx->substate_activated ==
		CAM_ISP_CTX_ACTIVATED_APPLIED) ||
		(isp_ctx->substate_activated ==
		CAM_ISP_CTX_ACTIVATED_BUBBLE_APPLIED))
		isp_dev->is_applied = true;
	else
		isp_dev->is_applied = false;

	return rc;
}

static int __cam_isp_ctx_get_dev_info_in_acquired(struct cam_context *ctx,
static int __cam_isp_ctx_get_dev_info_in_acquired(struct cam_context *ctx,
	struct cam_req_mgr_device_info *dev_info)
	struct cam_req_mgr_device_info *dev_info)
{
{
@@ -5238,6 +5375,7 @@ static int __cam_isp_ctx_get_dev_info_in_acquired(struct cam_context *ctx,
	dev_info->p_delay = 1;
	dev_info->p_delay = 1;
	dev_info->trigger = CAM_TRIGGER_POINT_SOF;
	dev_info->trigger = CAM_TRIGGER_POINT_SOF;
	dev_info->trigger_on = true;
	dev_info->trigger_on = true;
	dev_info->sof_ts_cb = &__cam_isp_ctx_get_isp_info;


	return rc;
	return rc;
}
}
@@ -5295,6 +5433,8 @@ static int __cam_isp_ctx_start_dev_in_ready(struct cam_context *ctx,
	atomic_set(&ctx_isp->process_bubble, 0);
	atomic_set(&ctx_isp->process_bubble, 0);
	atomic_set(&ctx_isp->rxd_epoch, 0);
	atomic_set(&ctx_isp->rxd_epoch, 0);
	ctx_isp->frame_id = 0;
	ctx_isp->frame_id = 0;
	ctx_isp->sof_timestamp_val = 0;
	ctx_isp->boot_timestamp = 0;
	ctx_isp->active_req_cnt = 0;
	ctx_isp->active_req_cnt = 0;
	ctx_isp->reported_req_id = 0;
	ctx_isp->reported_req_id = 0;
	ctx_isp->bubble_frame_cnt = 0;
	ctx_isp->bubble_frame_cnt = 0;
@@ -5644,6 +5784,33 @@ static int __cam_isp_ctx_unlink_in_activated(struct cam_context *ctx,
	return rc;
	return rc;
}
}


static int __cam_isp_ctx_change_state_req(struct cam_context *ctx,
	struct cam_req_mgr_request_change_state *state_info)
{
	int rc = 0;
	struct cam_ctx_ops *ctx_ops = NULL;
	struct cam_isp_context *ctx_isp =
		(struct cam_isp_context *) ctx->ctx_priv;

	CAM_DBG(CAM_ISP, "Enter: changes state ctx id %d link 0x%x",
		ctx->ctx_id, ctx->link_hdl);
	ctx_ops = &ctx_isp->substate_machine[ctx_isp->substate_activated];
	if (ctx_ops->crm_ops.change_state) {
		rc = ctx_ops->crm_ops.change_state(ctx, state_info);
	} else {
		CAM_WARN_RATE_LIMIT(CAM_ISP,
		"No handle function in activated Substate[%s]",
			__cam_isp_ctx_substate_val_to_type(
			ctx_isp->substate_activated));
		rc = -EFAULT;
	}

	if (rc)
		CAM_WARN_RATE_LIMIT(CAM_ISP,
			"changes state failed");
	return rc;
}

static int __cam_isp_ctx_apply_req(struct cam_context *ctx,
static int __cam_isp_ctx_apply_req(struct cam_context *ctx,
	struct cam_req_mgr_apply_request *apply)
	struct cam_req_mgr_apply_request *apply)
{
{
@@ -5796,6 +5963,7 @@ static struct cam_ctx_ops
			.flush_req = __cam_isp_ctx_flush_req_in_top_state,
			.flush_req = __cam_isp_ctx_flush_req_in_top_state,
			.process_evt = __cam_isp_ctx_process_evt,
			.process_evt = __cam_isp_ctx_process_evt,
			.dump_req = __cam_isp_ctx_dump_in_top_state,
			.dump_req = __cam_isp_ctx_dump_in_top_state,
			.change_state = __cam_isp_ctx_change_state_req,
		},
		},
		.irq_ops = __cam_isp_ctx_handle_irq_in_activated,
		.irq_ops = __cam_isp_ctx_handle_irq_in_activated,
		.pagefault_ops = cam_isp_context_dump_requests,
		.pagefault_ops = cam_isp_context_dump_requests,
@@ -6020,6 +6188,8 @@ int cam_isp_context_init(struct cam_isp_context *ctx,


	ctx->base = ctx_base;
	ctx->base = ctx_base;
	ctx->frame_id = 0;
	ctx->frame_id = 0;
	ctx->sof_timestamp_val = 0;
	ctx->boot_timestamp = 0;
	ctx->custom_enabled = false;
	ctx->custom_enabled = false;
	ctx->use_frame_header_ts = false;
	ctx->use_frame_header_ts = false;
	ctx->active_req_cnt = 0;
	ctx->active_req_cnt = 0;
Loading