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

Commit eabdd6c9 authored by Venkat Chinta's avatar Venkat Chinta Committed by Gerrit - the friendly Code Review server
Browse files

msm: camera: isp: Config hardware in work queue



Currently requests for offline IFE are applied from tasklet
context or from an ioctl thread within a critical section
protected by a spinlock. In both of these cases, preemtion is
disabled but CDM requires mutex locks during this operation.
Therefore a work queue is added in this change to handle
apply request for offline IFE.

CRs-Fixed: 2606911
Change-Id: Ie893a626bc274d026fb878f1f19830e990be6dc6
Signed-off-by: default avatarVenkat Chinta <vchinta@codeaurora.org>
parent f20a8087
Loading
Loading
Loading
Loading
+55 −13
Original line number Diff line number Diff line
@@ -979,14 +979,22 @@ static int __cam_isp_ctx_handle_buf_done_in_activated_state(
}

static int __cam_isp_ctx_apply_req_offline(
	struct cam_context *ctx, uint32_t next_state,
	struct cam_isp_context *ctx_isp)
	void *priv, void *data)
{
	int rc = 0;
	struct cam_context *ctx = NULL;
	struct cam_isp_context *ctx_isp = priv;
	struct cam_ctx_request *req;
	struct cam_isp_ctx_req *req_isp;
	struct cam_hw_config_args cfg;

	if (!ctx_isp) {
		CAM_ERR(CAM_ISP, "Invalid ctx_isp:%pK", ctx);
		rc = -EINVAL;
		goto end;
	}
	ctx = ctx_isp->base;

	if (list_empty(&ctx->pending_req_list)) {
		CAM_DBG(CAM_ISP, "No pending requests to apply");
		rc = -EFAULT;
@@ -999,8 +1007,10 @@ static int __cam_isp_ctx_apply_req_offline(
	if (ctx_isp->active_req_cnt >= 2)
		goto end;

	spin_lock_bh(&ctx->lock);
	req = list_first_entry(&ctx->pending_req_list, struct cam_ctx_request,
		list);
	spin_unlock_bh(&ctx->lock);

	CAM_DBG(CAM_REQ, "Apply request %lld in substate %d ctx %u",
		req->request_id, ctx_isp->substate_activated, ctx->ctx_id);
@@ -1019,13 +1029,21 @@ static int __cam_isp_ctx_apply_req_offline(
	if (rc) {
		CAM_ERR_RATE_LIMIT(CAM_ISP, "Can not apply the configuration");
	} else {
		spin_lock_bh(&ctx->lock);

		atomic_set(&ctx_isp->rxd_epoch, 0);
		ctx_isp->substate_activated = next_state;

		ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_APPLIED;
		ctx_isp->last_applied_req_id = req->request_id;

		list_del_init(&req->list);
		list_add_tail(&req->list, &ctx->wait_req_list);

		spin_unlock_bh(&ctx->lock);

		CAM_DBG(CAM_ISP, "New substate state %d, applied req %lld",
			next_state, ctx_isp->last_applied_req_id);
			CAM_ISP_CTX_ACTIVATED_APPLIED,
			ctx_isp->last_applied_req_id);

		__cam_isp_ctx_update_state_monitor_array(ctx_isp,
			CAM_ISP_STATE_CHANGE_TRIGGER_APPLIED,
@@ -1035,6 +1053,26 @@ static int __cam_isp_ctx_apply_req_offline(
	return rc;
}

static int __cam_isp_ctx_schedule_apply_req_offline(
	struct cam_isp_context *ctx_isp)
{
	int rc = 0;
	struct crm_workq_task *task;

	task = cam_req_mgr_workq_get_task(ctx_isp->workq);
	if (!task) {
		CAM_ERR(CAM_ISP, "No task for worker");
		return -ENOMEM;
	}

	task->process_cb = __cam_isp_ctx_apply_req_offline;
	rc = cam_req_mgr_workq_enqueue_task(task, ctx_isp, CRM_TASK_PRIORITY_0);
	if (rc)
		CAM_ERR(CAM_ISP, "Failed to schedule task rc:%d", rc);

	return rc;
}

static int __cam_isp_ctx_offline_epoch_in_activated_state(
	struct cam_isp_context *ctx_isp, void *evt_data)
{
@@ -1055,8 +1093,7 @@ static int __cam_isp_ctx_offline_epoch_in_activated_state(
		}
	}

	__cam_isp_ctx_apply_req_offline(ctx, CAM_ISP_CTX_ACTIVATED_APPLIED,
		ctx_isp);
	__cam_isp_ctx_schedule_apply_req_offline(ctx_isp);

	__cam_isp_ctx_send_sof_timestamp(ctx_isp, request_id,
		CAM_REQ_MGR_SOF_EVENT_SUCCESS);
@@ -3818,10 +3855,7 @@ static int __cam_isp_ctx_config_dev_in_top_state(
		req->request_id, ctx->ctx_id);

	if (ctx_isp->offline_context && atomic_read(&ctx_isp->rxd_epoch)) {
		spin_lock_bh(&ctx->lock);
		__cam_isp_ctx_apply_req_offline(ctx,
			CAM_ISP_CTX_ACTIVATED_APPLIED, ctx_isp);
		spin_unlock_bh(&ctx->lock);
		__cam_isp_ctx_schedule_apply_req_offline(ctx_isp);
	}

	return rc;
@@ -4267,6 +4301,13 @@ static int __cam_isp_ctx_acquire_hw_v2(struct cam_context *ctx,
			cam_isp_ctx_offline_state_machine_irq;
		ctx_isp->substate_machine = NULL;
		ctx_isp->offline_context = true;

		rc = cam_req_mgr_workq_create("offline_ife", 20,
			&ctx_isp->workq, CRM_WORKQ_USAGE_IRQ, 0);
		if (rc)
			CAM_ERR(CAM_ISP,
				"Failed to create workq for offline IFE rc:%d",
				rc);
	} else {
		CAM_DBG(CAM_ISP, "Session has PIX or PIX and RDI resources");
		ctx_isp->substate_machine_irq =
@@ -5180,6 +5221,7 @@ int cam_isp_context_init(struct cam_isp_context *ctx,
		atomic64_set(&ctx->event_record_head[i], -1);

	cam_isp_context_debug_register();

err:
	return rc;
}
+3 −1
Original line number Diff line number Diff line
@@ -13,7 +13,7 @@

#include "cam_context.h"
#include "cam_isp_hw_mgr_intf.h"

#include "cam_req_mgr_workq.h"

#define CAM_IFE_QTIMER_MUL_FACTOR        10000
#define CAM_IFE_QTIMER_DIV_FACTOR        192
@@ -254,6 +254,7 @@ struct cam_isp_context_event_record {
 * @init_timestamp:            Timestamp at which this context is initialized
 * @rxd_epoch:                 Indicate whether epoch has been received. Used to
 *                             decide whether to apply request in offline ctx
 * @workq:                     Worker thread for offline ife
 *
 */
struct cam_isp_context {
@@ -294,6 +295,7 @@ struct cam_isp_context {
	bool                                  use_frame_header_ts;
	unsigned int                          init_timestamp;
	atomic_t                              rxd_epoch;
	struct cam_req_mgr_core_workq        *workq;
};

/**
+19 −10
Original line number Diff line number Diff line
@@ -669,6 +669,11 @@ static void cam_ife_hw_mgr_print_acquire_info(

	hw_mgr_res = list_first_entry(&hw_mgr_ctx->res_list_ife_csid,
		struct cam_ife_hw_mgr_res, list);

	if (hw_mgr_ctx->is_offline)
		hw_mgr_res = list_first_entry(&hw_mgr_ctx->res_list_ife_src,
			struct cam_ife_hw_mgr_res, list);

	for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) {
		hw_res = hw_mgr_res->hw_res[i];
		if (hw_res && hw_res->hw_intf)
@@ -2158,7 +2163,7 @@ static int cam_ife_hw_mgr_preprocess_port(
	return 0;
}

static int cam_ife_hw_mgr_acquire_offline_res_ife_bus_rd(
static int cam_ife_hw_mgr_acquire_res_ife_bus_rd(
	struct cam_ife_hw_mgr_ctx                  *ife_ctx,
	struct cam_isp_in_port_generic_info        *in_port)
{
@@ -2373,7 +2378,7 @@ static int cam_ife_hw_mgr_acquire_offline_res_ife_camif(
	return rc;
}

static int cam_ife_mgr_acquire_hw_for_fe_ctx(
static int cam_ife_mgr_acquire_hw_for_offline_ctx(
	struct cam_ife_hw_mgr_ctx           *ife_ctx,
	struct cam_isp_in_port_generic_info *in_port,
	uint32_t                            *num_pix_port,
@@ -2405,7 +2410,7 @@ static int cam_ife_mgr_acquire_hw_for_fe_ctx(
		return -EINVAL;
	}

	rc = cam_ife_hw_mgr_acquire_offline_res_ife_bus_rd(ife_ctx, in_port);
	rc = cam_ife_hw_mgr_acquire_res_ife_bus_rd(ife_ctx, in_port);

	if (rc) {
		CAM_ERR(CAM_ISP, "Acquire IFE BUS RD resource Failed");
@@ -2473,17 +2478,21 @@ static int cam_ife_mgr_acquire_hw_for_ctx(
	cam_ife_hw_mgr_preprocess_port(ife_ctx, in_port, &ipp_count,
		&rdi_count, &ppp_count, &ife_rd_count, &lcr_count);

	if (ife_rd_count) {
		CAM_ERR(CAM_ISP, "Invalid BUS RD port for non-FE ctx");
		return -EINVAL;
	}

	if (!ipp_count && !rdi_count && !ppp_count && !lcr_count) {
		CAM_ERR(CAM_ISP,
			"No PIX or RDI or PPP or LCR resource");
		return -EINVAL;
	}

	if (ife_rd_count) {
		rc = cam_ife_hw_mgr_acquire_res_ife_bus_rd(ife_ctx, in_port);

		if (rc) {
			CAM_ERR(CAM_ISP, "Acquire IFE BUS RD resource Failed");
			goto err;
		}
	}

	if (ipp_count || lcr_count) {
		/* get ife csid IPP resource */
		rc = cam_ife_hw_mgr_acquire_res_ife_csid_pxl(ife_ctx,
@@ -2913,8 +2922,8 @@ static int cam_ife_mgr_acquire_hw(void *hw_mgr_priv, void *acquire_hw_args)
			ife_ctx->use_frame_header_ts = true;
		}

		if (ife_ctx->is_fe_enabled)
			rc = cam_ife_mgr_acquire_hw_for_fe_ctx(
		if (ife_ctx->is_offline)
			rc = cam_ife_mgr_acquire_hw_for_offline_ctx(
				ife_ctx, in_port,
				&num_pix_port_per_in,
				&acquire_args->acquired_hw_id[i],