Skip to content

Commit

Permalink
msm: camera: isp: Handle wait and active list during flush all
Browse files Browse the repository at this point in the history
If umd issues flush all, isp driver need to make sure that wait and
active list requests also flushed and corresponding buffer fences
needed to returned.

For active 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: Ibc57e64fbcef07de13520f2b9e4cc37c7c62bb37
Signed-off-by: Ravikishore Pampana <[email protected]>
  • Loading branch information
Ravikishore Pampana committed Jul 16, 2019
1 parent f22ad65 commit 1c55b1b
Show file tree
Hide file tree
Showing 4 changed files with 119 additions and 18 deletions.
12 changes: 12 additions & 0 deletions drivers/media/platform/msm/camera/cam_core/cam_hw_mgr_intf.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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 {
Expand All @@ -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_ */
66 changes: 60 additions & 6 deletions drivers/media/platform/msm/camera/cam_isp/cam_isp_context.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand All @@ -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;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -4025,10 +4071,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,
Expand Down Expand Up @@ -5852,6 +5894,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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -566,10 +566,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);
Expand All @@ -584,10 +580,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;

Expand Down

1 comment on commit 1c55b1b

@stefanhh0
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The commit is already included in the commit with the ID: f5d777a

Please sign in to comment.