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

Commit c91892ab authored by Mangalaram ARCHANA's avatar Mangalaram ARCHANA
Browse files

msm: camera: isp: After flush resetting the hardware



For active list and wait list flush, ife hardware need to stop at
frame boundary and release the fences. Ife hardware need to reset to
make sure that vfe bus write master fifos are cleared. Start the ife
hardware after reset and set the isp context state to sof.

Change-Id: Ic931b84f4eb99b892cd67274b0d461afc8bedf3e
Signed-off-by: default avatarMangalaram ARCHANA <mangar@codeaurora.org>
parent 802d279d
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -245,6 +245,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,
@@ -294,6 +304,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 {
@@ -312,6 +323,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_ */
+20 −6
Original line number Diff line number Diff line
@@ -1399,9 +1399,11 @@ static int __cam_isp_ctx_flush_req_in_top_state(
	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;
	int rc = 0;

	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);
	spin_unlock_bh(&ctx->lock);
@@ -1412,7 +1414,9 @@ static int __cam_isp_ctx_flush_req_in_top_state(
		if ((list_empty(&ctx->wait_req_list)) &&
			(list_empty(&ctx->active_req_list))) {
			spin_unlock_bh(&ctx->lock);
			CAM_DBG(CAM_ISP, "active and wait list are empty");
			CAM_DBG(CAM_ISP,
				"ctx id:%d active and wait list are empty",
				ctx->ctx_id);
			goto end;
		}
		spin_unlock_bh(&ctx->lock);
@@ -1424,12 +1428,21 @@ static int __cam_isp_ctx_flush_req_in_top_state(
		stop_args.args = (void *)&stop_isp;
		ctx->hw_mgr_intf->hw_stop(ctx->hw_mgr_intf->hw_mgr_priv,
				&stop_args);
		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;

		spin_lock_bh(&ctx->lock);
		CAM_DBG(CAM_ISP, "try to flush wait list");
		CAM_DBG(CAM_ISP, "ctx id:%d try to flush wait list",
			ctx->ctx_id);
		rc = __cam_isp_ctx_flush_req(ctx, &ctx->wait_req_list,
		flush_req);
		CAM_DBG(CAM_ISP, "try to flush active list");
		CAM_DBG(CAM_ISP, "ctx id:%d try to flush active list",
			ctx->ctx_id);
		rc = __cam_isp_ctx_flush_req(ctx, &ctx->active_req_list,
		flush_req);
		ctx_isp->active_req_cnt = 0;
@@ -1445,8 +1458,9 @@ static int __cam_isp_ctx_flush_req_in_top_state(
	}

end:
	CAM_DBG(CAM_ISP, "Flush request in top state %d",
		 ctx->state);
	ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_SOF;
	CAM_DBG(CAM_ISP, "ctx id:%d Flush request in top state %d",
		 ctx->ctx_id, ctx->state);
	return rc;
}

+42 −5
Original line number Diff line number Diff line
@@ -1940,6 +1940,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)
{
@@ -2344,6 +2349,42 @@ 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)
{
@@ -2854,11 +2895,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,
	uint32_t sof_irq_enable)
@@ -4593,6 +4629,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
@@ -506,10 +506,6 @@ static int cam_ife_csid_path_reset(struct cam_ife_csid_hw *csid_hw,
	reinit_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);
@@ -524,10 +520,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;