|
@@ -368,6 +368,11 @@ static void cam_ife_hw_mgr_stop_hw_res(
|
|
if (!isp_hw_res->hw_res[i])
|
|
if (!isp_hw_res->hw_res[i])
|
|
continue;
|
|
continue;
|
|
hw_intf = isp_hw_res->hw_res[i]->hw_intf;
|
|
hw_intf = isp_hw_res->hw_res[i]->hw_intf;
|
|
|
|
+
|
|
|
|
+ if (isp_hw_res->hw_res[i]->res_state !=
|
|
|
|
+ CAM_ISP_RESOURCE_STATE_STREAMING)
|
|
|
|
+ continue;
|
|
|
|
+
|
|
if (hw_intf->hw_ops.stop)
|
|
if (hw_intf->hw_ops.stop)
|
|
hw_intf->hw_ops.stop(hw_intf->hw_priv,
|
|
hw_intf->hw_ops.stop(hw_intf->hw_priv,
|
|
isp_hw_res->hw_res[i],
|
|
isp_hw_res->hw_res[i],
|
|
@@ -794,7 +799,9 @@ static int cam_ife_mgr_csid_stop_hw(
|
|
cnt = 0;
|
|
cnt = 0;
|
|
list_for_each_entry(hw_mgr_res, stop_list, list) {
|
|
list_for_each_entry(hw_mgr_res, stop_list, list) {
|
|
for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) {
|
|
for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) {
|
|
- if (!hw_mgr_res->hw_res[i])
|
|
|
|
|
|
+ if (!hw_mgr_res->hw_res[i] ||
|
|
|
|
+ (hw_mgr_res->hw_res[i]->res_state !=
|
|
|
|
+ CAM_ISP_RESOURCE_STATE_STREAMING))
|
|
continue;
|
|
continue;
|
|
|
|
|
|
isp_res = hw_mgr_res->hw_res[i];
|
|
isp_res = hw_mgr_res->hw_res[i];
|
|
@@ -2722,6 +2729,7 @@ static int cam_ife_mgr_acquire_hw(void *hw_mgr_priv, void *acquire_hw_args)
|
|
cdm_acquire.handle);
|
|
cdm_acquire.handle);
|
|
ife_ctx->cdm_handle = cdm_acquire.handle;
|
|
ife_ctx->cdm_handle = cdm_acquire.handle;
|
|
ife_ctx->cdm_ops = cdm_acquire.ops;
|
|
ife_ctx->cdm_ops = cdm_acquire.ops;
|
|
|
|
+ atomic_set(&ife_ctx->cdm_done, 1);
|
|
|
|
|
|
acquire_hw_info =
|
|
acquire_hw_info =
|
|
(struct cam_isp_acquire_hw_info *)acquire_args->acquire_info;
|
|
(struct cam_isp_acquire_hw_info *)acquire_args->acquire_info;
|
|
@@ -2910,6 +2918,7 @@ static int cam_ife_mgr_acquire_dev(void *hw_mgr_priv, void *acquire_hw_args)
|
|
cdm_acquire.handle);
|
|
cdm_acquire.handle);
|
|
ife_ctx->cdm_handle = cdm_acquire.handle;
|
|
ife_ctx->cdm_handle = cdm_acquire.handle;
|
|
ife_ctx->cdm_ops = cdm_acquire.ops;
|
|
ife_ctx->cdm_ops = cdm_acquire.ops;
|
|
|
|
+ atomic_set(&ife_ctx->cdm_done, 1);
|
|
|
|
|
|
isp_resource = (struct cam_isp_resource *)acquire_args->acquire_info;
|
|
isp_resource = (struct cam_isp_resource *)acquire_args->acquire_info;
|
|
|
|
|
|
@@ -3623,13 +3632,6 @@ static int cam_ife_mgr_stop_hw(void *hw_mgr_priv, void *stop_hw_args)
|
|
CAM_DBG(CAM_ISP, " Enter...ctx id:%d", ctx->ctx_index);
|
|
CAM_DBG(CAM_ISP, " Enter...ctx id:%d", ctx->ctx_index);
|
|
stop_isp = (struct cam_isp_stop_args *)stop_args->args;
|
|
stop_isp = (struct cam_isp_stop_args *)stop_args->args;
|
|
|
|
|
|
- if ((stop_isp->hw_stop_cmd == CAM_ISP_HW_STOP_IMMEDIATELY) &&
|
|
|
|
- (stop_isp->stop_only)) {
|
|
|
|
- CAM_ERR(CAM_ISP, "Invalid params hw_stop_cmd:%d stop_only:%d",
|
|
|
|
- stop_isp->hw_stop_cmd, stop_isp->stop_only);
|
|
|
|
- return -EPERM;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
/* Set the csid halt command */
|
|
/* Set the csid halt command */
|
|
if (stop_isp->hw_stop_cmd == CAM_ISP_HW_STOP_AT_FRAME_BOUNDARY)
|
|
if (stop_isp->hw_stop_cmd == CAM_ISP_HW_STOP_AT_FRAME_BOUNDARY)
|
|
csid_halt_type = CAM_CSID_HALT_AT_FRAME_BOUNDARY;
|
|
csid_halt_type = CAM_CSID_HALT_AT_FRAME_BOUNDARY;
|
|
@@ -3663,7 +3665,7 @@ static int cam_ife_mgr_stop_hw(void *hw_mgr_priv, void *stop_hw_args)
|
|
|
|
|
|
/* Stop the master CSID path first */
|
|
/* Stop the master CSID path first */
|
|
cam_ife_mgr_csid_stop_hw(ctx, &ctx->res_list_ife_csid,
|
|
cam_ife_mgr_csid_stop_hw(ctx, &ctx->res_list_ife_csid,
|
|
- master_base_idx, CAM_CSID_HALT_AT_FRAME_BOUNDARY);
|
|
|
|
|
|
+ master_base_idx, csid_halt_type);
|
|
|
|
|
|
/* stop rest of the CSID paths */
|
|
/* stop rest of the CSID paths */
|
|
for (i = 0; i < ctx->num_base; i++) {
|
|
for (i = 0; i < ctx->num_base; i++) {
|
|
@@ -3673,7 +3675,7 @@ static int cam_ife_mgr_stop_hw(void *hw_mgr_priv, void *stop_hw_args)
|
|
ctx->base[i].idx, i, master_base_idx);
|
|
ctx->base[i].idx, i, master_base_idx);
|
|
|
|
|
|
cam_ife_mgr_csid_stop_hw(ctx, &ctx->res_list_ife_csid,
|
|
cam_ife_mgr_csid_stop_hw(ctx, &ctx->res_list_ife_csid,
|
|
- ctx->base[i].idx, CAM_CSID_HALT_AT_FRAME_BOUNDARY);
|
|
|
|
|
|
+ ctx->base[i].idx, csid_halt_type);
|
|
}
|
|
}
|
|
|
|
|
|
CAM_DBG(CAM_ISP, "Stopping master CID idx %d", master_base_idx);
|
|
CAM_DBG(CAM_ISP, "Stopping master CID idx %d", master_base_idx);
|
|
@@ -3714,6 +3716,8 @@ static int cam_ife_mgr_stop_hw(void *hw_mgr_priv, void *stop_hw_args)
|
|
|
|
|
|
cam_ife_mgr_pause_hw(ctx);
|
|
cam_ife_mgr_pause_hw(ctx);
|
|
|
|
|
|
|
|
+ wait_for_completion(&ctx->config_done_complete);
|
|
|
|
+
|
|
if (stop_isp->stop_only)
|
|
if (stop_isp->stop_only)
|
|
goto end;
|
|
goto end;
|
|
|
|
|
|
@@ -3945,6 +3949,7 @@ static int cam_ife_mgr_start_hw(void *hw_mgr_priv, void *start_hw_args)
|
|
goto safe_disable;
|
|
goto safe_disable;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+start_only:
|
|
/* Apply initial configuration */
|
|
/* Apply initial configuration */
|
|
CAM_DBG(CAM_ISP, "Config HW");
|
|
CAM_DBG(CAM_ISP, "Config HW");
|
|
rc = cam_ife_mgr_config_hw(hw_mgr_priv, &start_isp->hw_config);
|
|
rc = cam_ife_mgr_config_hw(hw_mgr_priv, &start_isp->hw_config);
|
|
@@ -3953,8 +3958,6 @@ static int cam_ife_mgr_start_hw(void *hw_mgr_priv, void *start_hw_args)
|
|
goto cdm_streamoff;
|
|
goto cdm_streamoff;
|
|
}
|
|
}
|
|
|
|
|
|
-start_only:
|
|
|
|
-
|
|
|
|
CAM_DBG(CAM_ISP, "START IFE OUT ... in ctx id:%d",
|
|
CAM_DBG(CAM_ISP, "START IFE OUT ... in ctx id:%d",
|
|
ctx->ctx_index);
|
|
ctx->ctx_index);
|
|
/* start the IFE out devices */
|
|
/* start the IFE out devices */
|
|
@@ -4081,6 +4084,48 @@ static int cam_ife_mgr_write(void *hw_mgr_priv, void *write_args)
|
|
return -EPERM;
|
|
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;
|
|
|
|
+ int rc = 0, i = 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");
|
|
|
|
+ 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 to reset CSID:%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);
|
|
|
|
+ if (rc) {
|
|
|
|
+ CAM_ERR(CAM_ISP, "Failed to reset VFE:%d rc: %d",
|
|
|
|
+ ctx->base[i].idx, rc);
|
|
|
|
+ goto end;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+end:
|
|
|
|
+ return rc;
|
|
|
|
+}
|
|
|
|
+
|
|
static int cam_ife_mgr_release_hw(void *hw_mgr_priv,
|
|
static int cam_ife_mgr_release_hw(void *hw_mgr_priv,
|
|
void *release_hw_args)
|
|
void *release_hw_args)
|
|
{
|
|
{
|
|
@@ -6807,6 +6852,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_prepare_update = cam_ife_mgr_prepare_hw_update;
|
|
hw_mgr_intf->hw_config = cam_ife_mgr_config_hw;
|
|
hw_mgr_intf->hw_config = cam_ife_mgr_config_hw;
|
|
hw_mgr_intf->hw_cmd = cam_ife_mgr_cmd;
|
|
hw_mgr_intf->hw_cmd = cam_ife_mgr_cmd;
|
|
|
|
+ hw_mgr_intf->hw_reset = cam_ife_mgr_reset;
|
|
|
|
|
|
if (iommu_hdl)
|
|
if (iommu_hdl)
|
|
*iommu_hdl = g_ife_hw_mgr.mgr_common.img_iommu_hdl;
|
|
*iommu_hdl = g_ife_hw_mgr.mgr_common.img_iommu_hdl;
|