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

Commit cb1a16e3 authored by Suresh Vankadara's avatar Suresh Vankadara Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: camera: isp: Handle wait and active list during flush all" into dev/msm-4.14-camx

parents 7a75626b 1c55b1bb
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -262,6 +262,16 @@ struct cam_hw_dump_pf_args {
	bool                           *mem_found;
};

/**
 * struct cam_hw_reset_args -hw reset arguments
 *
 * @ctxt_to_hw_map:        HW context from the acquire
 *
 */
struct cam_hw_reset_args {
	void                           *ctxt_to_hw_map;
};

/* enum cam_hw_mgr_command - Hardware manager command type */
enum cam_hw_mgr_command {
	CAM_HW_MGR_CMD_INTERNAL,
@@ -313,6 +323,7 @@ struct cam_hw_cmd_args {
 * @hw_open:                   Function pointer for HW init
 * @hw_close:                  Function pointer for HW deinit
 * @hw_flush:                  Function pointer for HW flush
 * @hw_reset:                  Function pointer for HW reset
 *
 */
struct cam_hw_mgr_intf {
@@ -333,6 +344,7 @@ struct cam_hw_mgr_intf {
	int (*hw_open)(void *hw_priv, void *fw_download_args);
	int (*hw_close)(void *hw_priv, void *hw_close_args);
	int (*hw_flush)(void *hw_priv, void *hw_flush_args);
	int (*hw_reset)(void *hw_priv, void *hw_reset_args);
};

#endif /* _CAM_HW_MGR_INTF_H_ */
+60 −6
Original line number Diff line number Diff line
@@ -1922,16 +1922,19 @@ static int __cam_isp_ctx_flush_req_in_top_state(
	struct cam_req_mgr_flush_request *flush_req)
{
	int rc = 0;
	struct cam_isp_context *ctx_isp;

	ctx_isp = (struct cam_isp_context *) ctx->ctx_priv;
	struct cam_isp_context           *ctx_isp =
		(struct cam_isp_context *) ctx->ctx_priv;
	struct cam_isp_stop_args          stop_isp;
	struct cam_hw_stop_args           stop_args;
	struct cam_isp_start_args         start_isp;
	struct cam_hw_reset_args          reset_args;
	if (flush_req->type == CAM_REQ_MGR_FLUSH_TYPE_ALL) {
		CAM_INFO(CAM_ISP, "Last request id to flush is %lld",
			flush_req->req_id);
		CAM_INFO(CAM_ISP, "ctx id:%d Last request id to flush is %lld",
			ctx->ctx_id, flush_req->req_id);
		ctx->last_flush_req = flush_req->req_id;
	}

	CAM_DBG(CAM_ISP, "try to flush pending list");
	CAM_DBG(CAM_ISP, "ctx id:%d try to flush pending list", ctx->ctx_id);
	spin_lock_bh(&ctx->lock);
	rc = __cam_isp_ctx_flush_req(ctx, &ctx->pending_req_list, flush_req);

@@ -1954,6 +1957,57 @@ static int __cam_isp_ctx_flush_req_in_top_state(
	spin_unlock_bh(&ctx->lock);

	atomic_set(&ctx_isp->process_bubble, 0);
	if (flush_req->type == CAM_REQ_MGR_FLUSH_TYPE_ALL) {
		/* if active and wait list are empty, return */
		spin_lock_bh(&ctx->lock);
		if ((list_empty(&ctx->wait_req_list)) &&
			(list_empty(&ctx->active_req_list))) {
			spin_unlock_bh(&ctx->lock);
			CAM_DBG(CAM_ISP, "ctx id:%d active,wait list are empty",
				ctx->ctx_id);
			goto end;
		}
		spin_unlock_bh(&ctx->lock);

		/* Stop hw first before active list flush */
		CAM_DBG(CAM_ISP, "ctx id:%d try to stop hw", ctx->ctx_id);
		stop_args.ctxt_to_hw_map = ctx_isp->hw_ctx;
		stop_isp.hw_stop_cmd = CAM_ISP_HW_STOP_AT_FRAME_BOUNDARY;
		stop_isp.stop_only = true;
		stop_args.args = (void *)&stop_isp;
		ctx->hw_mgr_intf->hw_stop(ctx->hw_mgr_intf->hw_mgr_priv,
				&stop_args);

		spin_lock_bh(&ctx->lock);
		CAM_DBG(CAM_ISP, "try to flush wait list");
		rc = __cam_isp_ctx_flush_req(ctx, &ctx->wait_req_list,
		flush_req);
		CAM_DBG(CAM_ISP, "try to flush active list");
		rc = __cam_isp_ctx_flush_req(ctx, &ctx->active_req_list,
		flush_req);
		ctx_isp->active_req_cnt = 0;
		spin_unlock_bh(&ctx->lock);

		CAM_DBG(CAM_ISP, "try to reset hw");
		/* Reset hw */
		reset_args.ctxt_to_hw_map = ctx_isp->hw_ctx;
		rc = ctx->hw_mgr_intf->hw_reset(ctx->hw_mgr_intf->hw_mgr_priv,
			&reset_args);
		if (rc)
			goto end;

		CAM_DBG(CAM_ISP, "ctx id%d try to start hw", ctx->ctx_id);
		/* Start hw */
		start_isp.hw_config.ctxt_to_hw_map = ctx_isp->hw_ctx;
		start_isp.start_only = true;
		start_isp.hw_config.priv = NULL;

		rc = ctx->hw_mgr_intf->hw_start(ctx->hw_mgr_intf->hw_mgr_priv,
			&start_isp);
	}

end:
	ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_SOF;
	return rc;
}

+47 −4
Original line number Diff line number Diff line
@@ -2572,6 +2572,11 @@ static int cam_ife_mgr_pause_hw(struct cam_ife_hw_mgr_ctx *ctx)
	return cam_ife_mgr_bw_control(ctx, CAM_VFE_BW_CONTROL_EXCLUDE);
}

static int cam_ife_mgr_resume_hw(struct cam_ife_hw_mgr_ctx *ctx)
{
	return cam_ife_mgr_bw_control(ctx, CAM_VFE_BW_CONTROL_INCLUDE);
}

/* entry function: stop_hw */
static int cam_ife_mgr_stop_hw(void *hw_mgr_priv, void *stop_hw_args)
{
@@ -2925,6 +2930,9 @@ static int cam_ife_mgr_start_hw(void *hw_mgr_priv, void *start_hw_args)

	CAM_DBG(CAM_ISP, "START IFE OUT ... in ctx id:%d",
		ctx->ctx_index);
	if (start_isp->start_only)
		cam_ife_mgr_resume_hw(ctx);

	/* start the IFE out devices */
	for (i = 0; i < CAM_IFE_HW_OUT_RES_MAX; i++) {
		rc = cam_ife_hw_mgr_start_hw_res(
@@ -3025,6 +3033,44 @@ static int cam_ife_mgr_write(void *hw_mgr_priv, void *write_args)
	return -EPERM;
}

static int cam_ife_mgr_reset(void *hw_mgr_priv, void *hw_reset_args)
{
	struct cam_ife_hw_mgr            *hw_mgr       = hw_mgr_priv;
	struct cam_hw_reset_args         *reset_args = hw_reset_args;
	struct cam_ife_hw_mgr_ctx        *ctx;
	struct cam_ife_hw_mgr_res        *hw_mgr_res;
	uint32_t                          i;
	int                               rc = 0;

	if (!hw_mgr_priv || !hw_reset_args) {
		CAM_ERR(CAM_ISP, "Invalid arguments");
		return -EINVAL;
	}

	ctx = (struct cam_ife_hw_mgr_ctx *)reset_args->ctxt_to_hw_map;
	if (!ctx || !ctx->ctx_in_use) {
		CAM_ERR(CAM_ISP, "Invalid context is used");
		return -EPERM;
	}

	CAM_DBG(CAM_ISP, "reset csid and vfe hw");
	list_for_each_entry(hw_mgr_res, &ctx->res_list_ife_csid,
		list) {
		rc = cam_ife_hw_mgr_reset_csid_res(hw_mgr_res);
		if (rc) {
			CAM_ERR(CAM_ISP, "Failed RESET (%d) rc:%d",
				hw_mgr_res->res_id, rc);
			goto end;
		}
	}

	for (i = 0; i < ctx->num_base; i++)
		rc = cam_ife_mgr_reset_vfe_hw(hw_mgr, ctx->base[i].idx);

end:
	return rc;
}

static int cam_ife_mgr_release_hw(void *hw_mgr_priv,
					void *release_hw_args)
{
@@ -4108,10 +4154,6 @@ static int cam_ife_mgr_prepare_hw_update(void *hw_mgr_priv,
	return rc;
}

static int cam_ife_mgr_resume_hw(struct cam_ife_hw_mgr_ctx *ctx)
{
	return cam_ife_mgr_bw_control(ctx, CAM_VFE_BW_CONTROL_INCLUDE);
}

static int cam_ife_mgr_sof_irq_debug(
	struct cam_ife_hw_mgr_ctx *ctx,
@@ -5935,6 +5977,7 @@ int cam_ife_hw_mgr_init(struct cam_hw_mgr_intf *hw_mgr_intf, int *iommu_hdl)
	hw_mgr_intf->hw_prepare_update = cam_ife_mgr_prepare_hw_update;
	hw_mgr_intf->hw_config = cam_ife_mgr_config_hw;
	hw_mgr_intf->hw_cmd = cam_ife_mgr_cmd;
	hw_mgr_intf->hw_reset = cam_ife_mgr_reset;

	if (iommu_hdl)
		*iommu_hdl = g_ife_hw_mgr.mgr_common.img_iommu_hdl;
+0 −8
Original line number Diff line number Diff line
@@ -573,10 +573,6 @@ static int cam_ife_csid_path_reset(struct cam_ife_csid_hw *csid_hw,
	init_completion(complete);
	reset_strb_val = csid_reg->cmn_reg->path_rst_stb_all;

	/* Enable the Test gen before reset */
	cam_io_w_mb(1,	csid_hw->hw_info->soc_info.reg_map[0].mem_base +
		csid_reg->tpg_reg->csid_tpg_ctrl_addr);

	/* Reset the corresponding ife csid path */
	cam_io_w_mb(reset_strb_val, soc_info->reg_map[0].mem_base +
				reset_strb_addr);
@@ -591,10 +587,6 @@ static int cam_ife_csid_path_reset(struct cam_ife_csid_hw *csid_hw,
			rc = -ETIMEDOUT;
	}

	/* Disable Test Gen after reset*/
	cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
		csid_reg->tpg_reg->csid_tpg_ctrl_addr);

end:
	return rc;