Bladeren bron

Merge "msm: camera: common: Merge camera-kernel.3.1 changes in camera-kernel.4.0" into camera-kernel.lnx.4.0

Camera Software Integration 4 jaren geleden
bovenliggende
commit
2712471048

+ 15 - 1
drivers/cam_cdm/cam_cdm_hw_core.c

@@ -1085,6 +1085,9 @@ static void cam_hw_cdm_reset_cleanup(
 			&core->bl_fifo[i].bl_request_list, entry) {
 			if (node->request_type ==
 					CAM_HW_CDM_BL_CB_CLIENT) {
+				CAM_DBG(CAM_CDM,
+					"Notifying client %d for tag %d",
+					node->client_hdl, node->bl_tag);
 				if (flush_hw)
 					cam_cdm_notify_clients(cdm_hw,
 						(node->client_hdl == handle) ?
@@ -1145,6 +1148,17 @@ static void cam_hw_cdm_work(struct work_struct *work)
 			if (core->bl_fifo[payload->fifo_idx].work_record)
 				core->bl_fifo[payload->fifo_idx].work_record--;
 
+			if (list_empty(&core->bl_fifo[payload->fifo_idx]
+					.bl_request_list)) {
+				CAM_INFO(CAM_CDM,
+					"Fifo list empty, idx %d tag %d arb %d",
+					payload->fifo_idx, payload->irq_data,
+					core->arbitration);
+				mutex_unlock(&core->bl_fifo[payload->fifo_idx]
+						.fifo_lock);
+				return;
+			}
+
 			if (core->bl_fifo[payload->fifo_idx]
 				.last_bl_tag_done !=
 				payload->irq_data) {
@@ -1174,7 +1188,7 @@ static void cam_hw_cdm_work(struct work_struct *work)
 					}
 				}
 			} else {
-				CAM_DBG(CAM_CDM,
+				CAM_INFO(CAM_CDM,
 					"Skip GenIRQ, tag 0x%x fifo %d",
 					payload->irq_data, payload->fifo_idx);
 			}

+ 20 - 10
drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe_bus.c

@@ -78,6 +78,7 @@ struct cam_tfe_bus_common_data {
 
 struct cam_tfe_bus_wm_resource_data {
 	uint32_t             index;
+	uint32_t             out_id;
 	struct cam_tfe_bus_common_data            *common_data;
 	struct cam_tfe_bus_reg_offset_bus_client  *hw_regs;
 
@@ -631,6 +632,7 @@ static int cam_tfe_bus_acquire_wm(
 	rsrc_data->height = out_port_info->height;
 	rsrc_data->stride = out_port_info->stride;
 	rsrc_data->mode = out_port_info->wm_mode;
+	rsrc_data->out_id = tfe_out_res_id;
 
 	/*
 	 * Store the acquire width, height separately. For frame based ports
@@ -644,14 +646,16 @@ static int cam_tfe_bus_acquire_wm(
 	/* Set WM offset value to default */
 	rsrc_data->offset  = 0;
 
-	if (rsrc_data->index > 6) {
+	if ((rsrc_data->index > 6) &&
+		(tfe_out_res_id != CAM_TFE_BUS_TFE_OUT_PDAF)) {
 		/* WM 7-9 refers to RDI 0/ RDI 1/RDI 2 */
 		rc = cam_tfe_bus_acquire_rdi_wm(rsrc_data);
 		if (rc)
 			return rc;
 
-	} else if (rsrc_data->index == 0 || rsrc_data->index == 1) {
-	/*  WM 0 FULL_OUT */
+	} else if (rsrc_data->index == 0 || rsrc_data->index == 1 ||
+		(tfe_out_res_id == CAM_TFE_BUS_TFE_OUT_PDAF)) {
+	/*  WM 0 FULL_OUT WM 1 IDEAL RAW WM9 for pdaf */
 		switch (rsrc_data->format) {
 		case CAM_FORMAT_MIPI_RAW_8:
 			rsrc_data->pack_fmt = 0x1;
@@ -747,9 +751,14 @@ static int cam_tfe_bus_start_wm(struct cam_isp_resource_node *wm_res)
 
 	/* Configure stride for RDIs on full TFE and TFE lite  */
 	if ((rsrc_data->index > 6) &&
-		(rsrc_data->mode != CAM_ISP_TFE_WM_LINE_BASED_MODE))
+		((rsrc_data->mode != CAM_ISP_TFE_WM_LINE_BASED_MODE) &&
+		(rsrc_data->out_id != CAM_TFE_BUS_TFE_OUT_PDAF))) {
 		cam_io_w_mb(rsrc_data->stride, (common_data->mem_base +
 			rsrc_data->hw_regs->image_cfg_2));
+		CAM_DBG(CAM_ISP, "WM:%d configure stride reg :0x%x",
+			rsrc_data->index,
+			rsrc_data->stride);
+	}
 
 	/* Enable WM */
 	cam_io_w_mb(rsrc_data->en_cfg, common_data->mem_base +
@@ -1183,9 +1192,9 @@ static int cam_tfe_bus_acquire_tfe_out(void *priv, void *acquire_args,
 	struct cam_tfe_bus_tfe_out_data        *rsrc_data = NULL;
 	enum cam_tfe_bus_tfe_out_id             tfe_out_res_id;
 	enum cam_tfe_bus_comp_grp_id            comp_grp_id;
-	int                                     rc = -ENODEV;
+	int                                     i, rc = -ENODEV;
 	uint32_t                                secure_caps = 0, mode;
-	uint32_t  i, format, num_wm, client_done_mask = 0;
+	uint32_t  format, num_wm, client_done_mask = 0;
 
 	if (!bus_priv || !acquire_args) {
 		CAM_ERR(CAM_ISP, "Invalid Param");
@@ -1310,10 +1319,10 @@ static int cam_tfe_bus_acquire_tfe_out(void *priv, void *acquire_args,
 
 release_wm:
 	for (i--; i >= 0; i--)
-		cam_tfe_bus_release_wm(bus_priv,
-			rsrc_data->wm_res[i]);
+		cam_tfe_bus_release_wm(bus_priv, rsrc_data->wm_res[i]);
 
-	cam_tfe_bus_release_comp_grp(bus_priv, rsrc_data->comp_grp);
+	if (rsrc_data->comp_grp)
+		cam_tfe_bus_release_comp_grp(bus_priv, rsrc_data->comp_grp);
 
 	return rc;
 }
@@ -1918,7 +1927,8 @@ static int cam_tfe_bus_update_wm(void *priv, void *cmd_args,
 			wm_data->index, reg_val_pair[j-1]);
 
 		if ((wm_data->index < 7) || ((wm_data->index >= 7) &&
-			(wm_data->mode == CAM_ISP_TFE_WM_LINE_BASED_MODE))) {
+			(wm_data->mode == CAM_ISP_TFE_WM_LINE_BASED_MODE)) ||
+			(wm_data->out_id == CAM_TFE_BUS_TFE_OUT_PDAF)) {
 			CAM_TFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
 				wm_data->hw_regs->image_cfg_2,
 				io_cfg->planes[i].plane_stride);

+ 0 - 17
drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe_core.c

@@ -1933,23 +1933,6 @@ static int cam_tfe_camif_resource_start(
 		return -ENODEV;
 	}
 
-	/* Camif module config */
-	val = cam_io_r(rsrc_data->mem_base +
-		rsrc_data->camif_reg->module_cfg);
-	val &= ~(rsrc_data->reg_data->pixel_pattern_mask);
-	val |= (rsrc_data->pix_pattern <<
-		rsrc_data->reg_data->pixel_pattern_shift);
-	val |= (1 << rsrc_data->reg_data->module_enable_shift);
-	val |= (1 << rsrc_data->reg_data->pix_out_enable_shift);
-	if (rsrc_data->camif_pd_enable)
-		val |= (1 << rsrc_data->reg_data->pdaf_output_enable_shift);
-
-	cam_io_w_mb(val, rsrc_data->mem_base +
-		rsrc_data->camif_reg->module_cfg);
-
-	CAM_DBG(CAM_ISP, "TFE:%d camif module config val:%d",
-		core_info->core_index, val);
-
 	/* Config tfe core*/
 	val = 0;
 	if (rsrc_data->sync_mode == CAM_ISP_HW_SYNC_SLAVE)

+ 14 - 0
drivers/cam_ope/cam_ope_context.c

@@ -123,6 +123,18 @@ static int __cam_ope_flush_dev_in_ready(struct cam_context *ctx,
 	return rc;
 }
 
+static int __cam_ope_dump_dev_in_ready(struct cam_context *ctx,
+	struct cam_dump_req_cmd *cmd)
+{
+	int rc;
+
+	rc = cam_context_dump_dev_to_hw(ctx, cmd);
+	if (rc)
+		CAM_ERR(CAM_OPE, "Failed to dump device");
+
+	return rc;
+}
+
 static int __cam_ope_config_dev_in_ready(struct cam_context *ctx,
 	struct cam_config_dev_cmd *cmd)
 {
@@ -206,6 +218,7 @@ static struct cam_ctx_ops
 			.start_dev = __cam_ope_start_dev_in_acquired,
 			.config_dev = __cam_ope_config_dev_in_ready,
 			.flush_dev = __cam_ope_flush_dev_in_ready,
+			.dump_dev = __cam_ope_dump_dev_in_ready,
 		},
 		.crm_ops = {},
 		.irq_ops = __cam_ope_handle_buf_done_in_ready,
@@ -218,6 +231,7 @@ static struct cam_ctx_ops
 			.release_dev = __cam_ope_release_dev_in_ready,
 			.config_dev = __cam_ope_config_dev_in_ready,
 			.flush_dev = __cam_ope_flush_dev_in_ready,
+			.dump_dev = __cam_ope_dump_dev_in_ready,
 		},
 		.crm_ops = {},
 		.irq_ops = __cam_ope_handle_buf_done_in_ready,

+ 296 - 44
drivers/cam_ope/ope_hw_mgr/cam_ope_hw_mgr.c

@@ -96,12 +96,19 @@ static int cam_ope_mgr_process_cmd(void *priv, void *data)
 	task_data = (struct ope_cmd_work_data *)data;
 	cdm_cmd = task_data->data;
 
-	CAM_DBG(CAM_OPE,
-		"cam_cdm_submit_bls: handle 0x%x, ctx_id %d req %d cookie %d",
-		ctx_data->ope_cdm.cdm_handle, ctx_data->ctx_id,
-		task_data->req_id, cdm_cmd->cookie);
+	if (!cdm_cmd) {
+		CAM_ERR(CAM_OPE, "Invalid params%pK", cdm_cmd);
+		return -EINVAL;
+	}
 
 	mutex_lock(&hw_mgr->hw_mgr_mutex);
+	if (ctx_data->ctx_state != OPE_CTX_STATE_ACQUIRED) {
+		mutex_unlock(&hw_mgr->hw_mgr_mutex);
+		CAM_ERR(CAM_OPE, "ctx id :%u is not in use",
+			ctx_data->ctx_id);
+		return -EINVAL;
+	}
+
 	if (task_data->req_id <= ctx_data->last_flush_req) {
 		CAM_WARN(CAM_OPE,
 			"request %lld has been flushed, reject packet",
@@ -110,6 +117,11 @@ static int cam_ope_mgr_process_cmd(void *priv, void *data)
 		return -EINVAL;
 	}
 
+	CAM_DBG(CAM_OPE,
+		"cam_cdm_submit_bls: handle 0x%x, ctx_id %d req %d cookie %d",
+		ctx_data->ope_cdm.cdm_handle, ctx_data->ctx_id,
+		task_data->req_id, cdm_cmd->cookie);
+
 	if (task_data->req_id > ctx_data->last_flush_req)
 		ctx_data->last_flush_req = 0;
 
@@ -536,13 +548,21 @@ static int cam_ope_dump_bls(struct cam_ope_request *ope_req,
 	struct cam_ope_hang_dump *dump)
 {
 	struct cam_cdm_bl_request *cdm_cmd;
-	int i;
+	size_t size;
+	int i, rc;
+	dma_addr_t iova_addr;
 
 	cdm_cmd = ope_req->cdm_cmd;
 	for (i = 0; i < cdm_cmd->cmd_arrary_count; i++) {
+		rc = cam_mem_get_io_buf(cdm_cmd->cmd[i].bl_addr.mem_handle,
+				ope_hw_mgr->iommu_hdl, &iova_addr, &size);
+		if (rc) {
+			CAM_ERR(CAM_OPE, "get io buf fail 0x%x",
+				cdm_cmd->cmd[i].bl_addr.mem_handle);
+			return rc;
+		}
 		dump->bl_entries[dump->num_bls].base =
-			(uint32_t)cdm_cmd->cmd[i].bl_addr.hw_iova +
-			cdm_cmd->cmd[i].offset;
+			(uint32_t)iova_addr + cdm_cmd->cmd[i].offset;
 		dump->bl_entries[dump->num_bls].len = cdm_cmd->cmd[i].len;
 		dump->bl_entries[dump->num_bls].arbitration =
 			cdm_cmd->cmd[i].arbitrate;
@@ -568,6 +588,7 @@ static void cam_ope_dump_req_data(struct cam_ope_request *ope_req)
 				ope_req->ope_debug_buf.offset);
 		return;
 	}
+
 	dump = (struct cam_ope_hang_dump *)ope_req->ope_debug_buf.cpu_addr;
 	memset(dump, 0, sizeof(struct cam_ope_hang_dump));
 	dump->num_bufs = 0;
@@ -1013,8 +1034,11 @@ static int cam_ope_get_lower_clk_rate(struct cam_ope_hw_mgr *hw_mgr,
 
 	i = cam_ope_get_actual_clk_rate_idx(ctx_data, base_clk);
 
-	if (i > 0)
-		return ctx_data->clk_info.clk_rate[i - 1];
+	while (i > 0) {
+		if (ctx_data->clk_info.clk_rate[i - 1])
+			return ctx_data->clk_info.clk_rate[i - 1];
+		i--;
+	}
 
 	CAM_DBG(CAM_OPE, "Already clk at lower level");
 
@@ -1028,8 +1052,11 @@ static int cam_ope_get_next_clk_rate(struct cam_ope_hw_mgr *hw_mgr,
 
 	i = cam_ope_get_actual_clk_rate_idx(ctx_data, base_clk);
 
-	if (i < CAM_MAX_VOTE - 1)
-		return ctx_data->clk_info.clk_rate[i + 1];
+	while (i < CAM_MAX_VOTE - 1) {
+		if (ctx_data->clk_info.clk_rate[i + 1])
+			return ctx_data->clk_info.clk_rate[i + 1];
+		i++;
+	}
 
 	CAM_DBG(CAM_OPE, "Already clk at higher level");
 
@@ -1520,6 +1547,7 @@ static void cam_ope_ctx_cdm_callback(uint32_t handle, void *userdata,
 	struct cam_hw_done_event_data buf_data;
 	struct timespec64 ts;
 	uint32_t evt_id = CAM_CTX_EVT_ID_SUCCESS;
+	bool dump_flag = true;
 
 	if (!userdata) {
 		CAM_ERR(CAM_OPE, "Invalid ctx from CDM callback");
@@ -1581,8 +1609,10 @@ static void cam_ope_ctx_cdm_callback(uint32_t handle, void *userdata,
 			 ope_req->request_id, ctx->ctx_id);
 		CAM_ERR(CAM_OPE, "Rst of CDM and OPE for error reqid = %lld",
 			ope_req->request_id);
-		if (status != CAM_CDM_CB_STATUS_HW_FLUSH)
+		if (status != CAM_CDM_CB_STATUS_HW_FLUSH) {
 			cam_ope_dump_req_data(ope_req);
+			dump_flag = false;
+		}
 		rc = cam_ope_mgr_reset_hw();
 		evt_id = CAM_CTX_EVT_ID_ERROR;
 
@@ -1598,6 +1628,9 @@ static void cam_ope_ctx_cdm_callback(uint32_t handle, void *userdata,
 			buf_data.evt_param = CAM_SYNC_OPE_EVENT_UNKNOWN;
 	}
 
+	if (ope_hw_mgr->dump_req_data_enable && dump_flag)
+		cam_ope_dump_req_data(ope_req);
+
 	ctx->req_cnt--;
 
 	buf_data.request_id = ope_req->request_id;
@@ -1779,15 +1812,14 @@ static void cam_ope_mgr_print_stripe_info(uint32_t batch,
 {
 	CAM_DBG(CAM_OPE, "b:%d io:%d p:%d s:%d: E",
 		batch, io_buf, plane, stripe);
-	CAM_DBG(CAM_OPE, "width: %d s_w: %u s_h: %u s_s: %u",
-		stripe_info->width, stripe_info->width,
-		stripe_info->height, stripe_info->stride);
+	CAM_DBG(CAM_OPE, "width: %d s_h: %u s_s: %u",
+		stripe_info->width, stripe_info->height,
+		stripe_info->stride);
 	CAM_DBG(CAM_OPE, "s_xinit = %u iova = %x s_loc = %u",
-		 stripe_info->s_location, stripe_info->x_init,
-		 iova_addr);
-	CAM_DBG(CAM_OPE, "s_off = %u s_format = %u s_len = %u",
+		stripe_info->x_init, iova_addr, stripe_info->s_location);
+	CAM_DBG(CAM_OPE, "s_off = %u s_format = %u s_len = %u d_bus %d",
 		stripe_info->offset, stripe_info->format,
-		stripe_info->len);
+		stripe_info->len, stripe_info->disable_bus);
 	CAM_DBG(CAM_OPE, "s_align = %u s_pack = %u s_unpack = %u",
 		stripe_info->alignment, stripe_info->pack_format,
 		stripe_info->unpack_format);
@@ -1827,29 +1859,15 @@ static int cam_ope_mgr_process_cmd_io_buf_req(struct cam_ope_hw_mgr *hw_mgr,
 		in_frame_set = &in_frame_process->frame_set[i];
 		for (j = 0; j < in_frame_set->num_io_bufs; j++) {
 			in_io_buf = &in_frame_set->io_buf[j];
-			CAM_DBG(CAM_OPE, "i:%d j:%d dir: %x rsc: %u plane: %d",
-				i, j, in_io_buf->direction,
-				in_io_buf->resource_type,
-				in_io_buf->num_planes);
 			for (k = 0; k < in_io_buf->num_planes; k++) {
-				CAM_DBG(CAM_OPE, "i:%d j:%d k:%d numstripe: %d",
-					i, j, k, in_io_buf->num_stripes[k]);
-				CAM_DBG(CAM_OPE, "m_hdl: %d len: %d",
-					in_io_buf->mem_handle[k],
-					in_io_buf->length[k]);
+				if (!in_io_buf->num_stripes[k]) {
+					CAM_ERR(CAM_OPE, "Null num_stripes");
+					return -EINVAL;
+				}
 				for (l = 0; l < in_io_buf->num_stripes[k];
 					l++) {
 					in_stripe_info =
 						&in_io_buf->stripe_info[k][l];
-					CAM_DBG(CAM_OPE, "i:%d j:%d k:%d l:%d",
-						i, j, k, l);
-					CAM_DBG(CAM_OPE, "%d s_loc:%d w:%d",
-						in_stripe_info->x_init,
-						in_stripe_info->stripe_location,
-						in_stripe_info->width);
-					CAM_DBG(CAM_OPE,  "s_off: %d d_bus: %d",
-						in_stripe_info->offset,
-						in_stripe_info->disable_bus);
 				}
 			}
 		}
@@ -1907,9 +1925,6 @@ static int cam_ope_mgr_process_cmd_io_buf_req(struct cam_ope_hw_mgr *hw_mgr,
 				unpack_format = 0;
 			}
 
-			CAM_DBG(CAM_OPE, "i:%d j:%d dir:%d rsc type:%d fmt:%d",
-				i, j, io_buf->direction, io_buf->resource_type,
-				io_buf->format);
 			for (k = 0; k < in_io_buf->num_planes; k++) {
 				io_buf->num_stripes[k] =
 					in_io_buf->num_stripes[k];
@@ -1936,6 +1951,11 @@ static int cam_ope_mgr_process_cmd_io_buf_req(struct cam_ope_hw_mgr *hw_mgr,
 					return -EINVAL;
 				}
 				iova_addr += in_io_buf->plane_offset[k];
+				CAM_DBG(CAM_OPE,
+					"E rsc %d stripes %d dir %d plane %d",
+					in_io_buf->resource_type,
+					in_io_buf->direction,
+					in_io_buf->num_stripes[k], k);
 				for (l = 0; l < in_io_buf->num_stripes[k];
 					l++) {
 					in_stripe_info =
@@ -1966,6 +1986,11 @@ static int cam_ope_mgr_process_cmd_io_buf_req(struct cam_ope_hw_mgr *hw_mgr,
 					cam_ope_mgr_print_stripe_info(i, j,
 						k, l, stripe_info, iova_addr);
 				}
+				CAM_DBG(CAM_OPE,
+					"X rsc %d stripes %d dir %d plane %d",
+					in_io_buf->resource_type,
+					in_io_buf->direction,
+					in_io_buf->num_stripes[k], k);
 			}
 		}
 	}
@@ -2491,6 +2516,9 @@ static int cam_ope_mgr_acquire_hw(void *hw_priv, void *hw_acquire_args)
 	struct cam_ope_dev_clk_update clk_update;
 	struct cam_ope_dev_bw_update *bw_update;
 	struct cam_ope_set_irq_cb irq_cb;
+	struct cam_hw_info *dev = NULL;
+	struct cam_hw_soc_info *soc_info = NULL;
+	int32_t idx;
 
 	if ((!hw_priv) || (!hw_acquire_args)) {
 		CAM_ERR(CAM_OPE, "Invalid args: %x %x",
@@ -2579,8 +2607,14 @@ static int cam_ope_mgr_acquire_hw(void *hw_priv, void *hw_acquire_args)
 			}
 		}
 
-		hw_mgr->clk_info.base_clk = 600000000;
-		hw_mgr->clk_info.curr_clk = 600000000;
+		dev = (struct cam_hw_info *)hw_mgr->ope_dev_intf[0]->hw_priv;
+		soc_info = &dev->soc_info;
+		idx = soc_info->src_clk_idx;
+
+		hw_mgr->clk_info.base_clk =
+			soc_info->clk_rate[CAM_TURBO_VOTE][idx];
+		hw_mgr->clk_info.curr_clk =
+			soc_info->clk_rate[CAM_TURBO_VOTE][idx];
 		hw_mgr->clk_info.threshold = 5;
 		hw_mgr->clk_info.over_clked = 0;
 
@@ -2607,7 +2641,11 @@ static int cam_ope_mgr_acquire_hw(void *hw_priv, void *hw_acquire_args)
 	}
 
 	for (i = 0; i < ope_hw_mgr->num_ope; i++) {
-		clk_update.clk_rate = 600000000;
+		dev = (struct cam_hw_info *)hw_mgr->ope_dev_intf[i]->hw_priv;
+		soc_info = &dev->soc_info;
+		idx = soc_info->src_clk_idx;
+		clk_update.clk_rate = soc_info->clk_rate[CAM_TURBO_VOTE][idx];
+
 		rc = hw_mgr->ope_dev_intf[i]->hw_ops.process_cmd(
 			hw_mgr->ope_dev_intf[i]->hw_priv, OPE_HW_CLK_UPDATE,
 			&clk_update, sizeof(clk_update));
@@ -3302,6 +3340,7 @@ static int cam_ope_mgr_config_hw(void *hw_priv, void *hw_config_args)
 	cdm_cmd->cookie = ope_req->req_idx;
 
 	cam_ope_mgr_ope_clk_update(hw_mgr, ctx_data, ope_req->req_idx);
+	ctx_data->req_list[ope_req->req_idx]->submit_timestamp = ktime_get();
 
 	if (ope_req->request_id <= ctx_data->last_flush_req)
 		CAM_WARN(CAM_OPE,
@@ -3327,6 +3366,112 @@ config_err:
 	return rc;
 }
 
+static void cam_ope_mgr_print_io_bufs(struct cam_packet *packet,
+	int32_t iommu_hdl, int32_t sec_mmu_hdl, uint32_t pf_buf_info,
+	bool *mem_found)
+{
+	dma_addr_t   iova_addr;
+	size_t     src_buf_size;
+	int        i;
+	int        j;
+	int        rc = 0;
+	int32_t    mmu_hdl;
+
+	struct cam_buf_io_cfg  *io_cfg = NULL;
+
+	if (mem_found)
+		*mem_found = false;
+
+	io_cfg = (struct cam_buf_io_cfg *)((uint32_t *)&packet->payload +
+		packet->io_configs_offset / 4);
+
+	for (i = 0; i < packet->num_io_configs; i++) {
+		for (j = 0; j < CAM_PACKET_MAX_PLANES; j++) {
+			if (!io_cfg[i].mem_handle[j])
+				break;
+
+			if (GET_FD_FROM_HANDLE(io_cfg[i].mem_handle[j]) ==
+				GET_FD_FROM_HANDLE(pf_buf_info)) {
+				CAM_INFO(CAM_OPE,
+					"Found PF at port: %d mem %x fd: %x",
+					io_cfg[i].resource_type,
+					io_cfg[i].mem_handle[j],
+					pf_buf_info);
+				if (mem_found)
+					*mem_found = true;
+			}
+
+			CAM_INFO(CAM_OPE, "port: %d f: %u format: %d dir %d",
+				io_cfg[i].resource_type,
+				io_cfg[i].fence,
+				io_cfg[i].format,
+				io_cfg[i].direction);
+
+			mmu_hdl = cam_mem_is_secure_buf(
+				io_cfg[i].mem_handle[j]) ? sec_mmu_hdl :
+				iommu_hdl;
+			rc = cam_mem_get_io_buf(io_cfg[i].mem_handle[j],
+				mmu_hdl, &iova_addr, &src_buf_size);
+			if (rc < 0) {
+				CAM_ERR(CAM_UTIL,
+					"get src buf address fail rc %d mem %x",
+					rc, io_cfg[i].mem_handle[j]);
+				continue;
+			}
+			if ((iova_addr & 0xFFFFFFFF) != iova_addr) {
+				CAM_ERR(CAM_OPE, "Invalid mapped address");
+				rc = -EINVAL;
+				continue;
+			}
+
+			CAM_INFO(CAM_OPE,
+				"pln %d dir %d w %d h %d s %u sh %u sz %d addr 0x%x off 0x%x memh %x",
+				j, io_cfg[i].direction,
+				io_cfg[i].planes[j].width,
+				io_cfg[i].planes[j].height,
+				io_cfg[i].planes[j].plane_stride,
+				io_cfg[i].planes[j].slice_height,
+				(int32_t)src_buf_size,
+				(unsigned int)iova_addr,
+				io_cfg[i].offsets[j],
+				io_cfg[i].mem_handle[j]);
+
+			iova_addr += io_cfg[i].offsets[j];
+
+		}
+	}
+	cam_packet_dump_patch_info(packet, ope_hw_mgr->iommu_hdl,
+		ope_hw_mgr->iommu_sec_hdl);
+}
+
+static int cam_ope_mgr_cmd(void *hw_mgr_priv, void *cmd_args)
+{
+	int rc = 0;
+	struct cam_hw_cmd_args *hw_cmd_args = cmd_args;
+	struct cam_ope_hw_mgr  *hw_mgr = hw_mgr_priv;
+
+	if (!hw_mgr_priv || !cmd_args) {
+		CAM_ERR(CAM_OPE, "Invalid arguments");
+		return -EINVAL;
+	}
+
+	switch (hw_cmd_args->cmd_type) {
+	case CAM_HW_MGR_CMD_DUMP_PF_INFO:
+		cam_ope_mgr_print_io_bufs(
+			hw_cmd_args->u.pf_args.pf_data.packet,
+			hw_mgr->iommu_hdl,
+			hw_mgr->iommu_sec_hdl,
+			hw_cmd_args->u.pf_args.buf_info,
+			hw_cmd_args->u.pf_args.mem_found);
+
+		break;
+	default:
+		CAM_ERR(CAM_OPE, "Invalid cmd");
+	}
+
+	return rc;
+}
+
 static int cam_ope_mgr_hw_open_u(void *hw_priv, void *fw_download_args)
 {
 	struct cam_ope_hw_mgr *hw_mgr;
@@ -3429,6 +3574,76 @@ static int cam_ope_mgr_flush_all(struct cam_ope_ctx *ctx_data,
 	return rc;
 }
 
+static int cam_ope_mgr_hw_dump(void *hw_priv, void *hw_dump_args)
+{
+	struct cam_ope_ctx *ctx_data;
+	struct cam_ope_hw_mgr *hw_mgr = hw_priv;
+	struct cam_hw_dump_args  *dump_args;
+	int idx;
+	ktime_t cur_time;
+	struct timespec64 cur_ts, req_ts;
+	uint64_t diff;
+
+	if ((!hw_priv) || (!hw_dump_args)) {
+		CAM_ERR(CAM_OPE, "Invalid params %pK %pK",
+			hw_priv, hw_dump_args);
+		return -EINVAL;
+	}
+
+	dump_args = (struct cam_hw_dump_args *)hw_dump_args;
+	ctx_data = dump_args->ctxt_to_hw_map;
+
+	if (!ctx_data) {
+		CAM_ERR(CAM_OPE, "Invalid context");
+		return -EINVAL;
+	}
+
+	mutex_lock(&hw_mgr->hw_mgr_mutex);
+
+	CAM_INFO(CAM_OPE, "Req %lld", dump_args->request_id);
+	for (idx = 0; idx < CAM_CTX_REQ_MAX; idx++) {
+		if (!ctx_data->req_list[idx])
+			continue;
+
+		if (ctx_data->req_list[idx]->request_id ==
+			dump_args->request_id)
+			break;
+	}
+
+	/* no matching request found */
+	if (idx == CAM_CTX_REQ_MAX) {
+		mutex_unlock(&hw_mgr->hw_mgr_mutex);
+		return 0;
+	}
+
+	cur_time = ktime_get();
+	diff = ktime_us_delta(cur_time,
+			ctx_data->req_list[idx]->submit_timestamp);
+	cur_ts = ktime_to_timespec64(cur_time);
+	req_ts = ktime_to_timespec64(ctx_data->req_list[idx]->submit_timestamp);
+
+	if (diff < (OPE_REQUEST_TIMEOUT * 1000)) {
+		CAM_INFO(CAM_OPE, "No Error req %llu %ld:%06ld %ld:%06ld",
+			dump_args->request_id,
+			req_ts.tv_sec,
+			req_ts.tv_nsec/NSEC_PER_USEC,
+			cur_ts.tv_sec,
+			cur_ts.tv_nsec/NSEC_PER_USEC);
+		mutex_unlock(&hw_mgr->hw_mgr_mutex);
+		return 0;
+	}
+
+	CAM_ERR(CAM_OPE, "Error req %llu %ld:%06ld %ld:%06ld",
+		dump_args->request_id,
+		req_ts.tv_sec,
+		req_ts.tv_nsec/NSEC_PER_USEC,
+		cur_ts.tv_sec,
+		cur_ts.tv_nsec/NSEC_PER_USEC);
+
+	mutex_unlock(&hw_mgr->hw_mgr_mutex);
+	return 0;
+}
+
 static int cam_ope_mgr_hw_flush(void *hw_priv, void *hw_flush_args)
 {
 	struct cam_hw_flush_args *flush_args = hw_flush_args;
@@ -3683,6 +3898,40 @@ cmd_work_failed:
 	return rc;
 }
 
+static int cam_ope_create_debug_fs(void)
+{
+	ope_hw_mgr->dentry = debugfs_create_dir("camera_ope",
+		NULL);
+
+	if (!ope_hw_mgr->dentry) {
+		CAM_ERR(CAM_OPE, "failed to create dentry");
+		return -ENOMEM;
+	}
+
+	if (!debugfs_create_bool("frame_dump_enable",
+		0644,
+		ope_hw_mgr->dentry,
+		&ope_hw_mgr->frame_dump_enable)) {
+		CAM_ERR(CAM_OPE,
+			"failed to create dump_enable_debug");
+		goto err;
+	}
+
+	if (!debugfs_create_bool("dump_req_data_enable",
+		0644,
+		ope_hw_mgr->dentry,
+		&ope_hw_mgr->dump_req_data_enable)) {
+		CAM_ERR(CAM_OPE,
+			"failed to create dump_enable_debug");
+		goto err;
+	}
+
+	return 0;
+err:
+	debugfs_remove_recursive(ope_hw_mgr->dentry);
+	return -ENOMEM;
+}
+
 
 int cam_ope_hw_mgr_init(struct device_node *of_node, uint64_t *hw_mgr_hdl,
 	int *iommu_hdl)
@@ -3716,10 +3965,11 @@ int cam_ope_hw_mgr_init(struct device_node *of_node, uint64_t *hw_mgr_hdl,
 	hw_mgr_intf->hw_config = cam_ope_mgr_config_hw;
 	hw_mgr_intf->hw_read   = NULL;
 	hw_mgr_intf->hw_write  = NULL;
-	hw_mgr_intf->hw_cmd = NULL;
+	hw_mgr_intf->hw_cmd = cam_ope_mgr_cmd;
 	hw_mgr_intf->hw_open = cam_ope_mgr_hw_open_u;
 	hw_mgr_intf->hw_close = cam_ope_mgr_hw_close_u;
 	hw_mgr_intf->hw_flush = cam_ope_mgr_hw_flush;
+	hw_mgr_intf->hw_dump = cam_ope_mgr_hw_dump;
 
 	ope_hw_mgr->secure_mode = false;
 	mutex_init(&ope_hw_mgr->hw_mgr_mutex);
@@ -3787,6 +4037,8 @@ int cam_ope_hw_mgr_init(struct device_node *of_node, uint64_t *hw_mgr_hdl,
 	if (rc)
 		goto ope_wq_create_failed;
 
+	cam_ope_create_debug_fs();
+
 	if (iommu_hdl)
 		*iommu_hdl = ope_hw_mgr->iommu_hdl;
 

+ 8 - 2
drivers/cam_ope/ope_hw_mgr/cam_ope_hw_mgr.h

@@ -62,8 +62,6 @@
 #define OPE_DEVICE_IDLE_TIMEOUT    400
 #define OPE_REQUEST_TIMEOUT        200
 
-
-
 /**
  * struct cam_ope_clk_bw_request_v2
  * @budget_ns: Time required to process frame
@@ -390,6 +388,7 @@ struct ope_io_buf {
  * @clk_info:            Clock Info V1
  * @clk_info_v2:         Clock Info V2
  * @hang_data:           Debug data for HW error
+ * @submit_timestamp:    Submit timestamp to hw
  */
 struct cam_ope_request {
 	uint64_t request_id;
@@ -410,6 +409,7 @@ struct cam_ope_request {
 	struct cam_ope_clk_bw_request clk_info;
 	struct cam_ope_clk_bw_req_internal_v2 clk_info_v2;
 	struct cam_hw_mgr_dump_pf_data hang_data;
+	ktime_t submit_timestamp;
 };
 
 /**
@@ -499,6 +499,9 @@ struct cam_ope_ctx {
  * @ope_dev_intf:      OPE device interface
  * @cdm_reg_map:       OPE CDM register map
  * @clk_info:          OPE clock Info for HW manager
+ * @dentry:            Pointer to OPE debugfs directory
+ * @frame_dump_enable: OPE frame setting dump enablement
+ * @dump_req_data_enable: OPE hang dump enablement
  */
 struct cam_ope_hw_mgr {
 	int32_t             open_cnt;
@@ -529,6 +532,9 @@ struct cam_ope_hw_mgr {
 	struct cam_hw_intf *ope_dev_intf[OPE_DEV_MAX];
 	struct cam_soc_reg_map *cdm_reg_map[OPE_DEV_MAX][OPE_BASE_MAX];
 	struct cam_ope_clk_info clk_info;
+	struct dentry *dentry;
+	bool   frame_dump_enable;
+	bool   dump_req_data_enable;
 };
 
 /**

+ 35 - 48
drivers/cam_ope/ope_hw_mgr/ope_hw/bus_rd/ope_bus_rd.c

@@ -193,13 +193,17 @@ static uint32_t *cam_ope_bus_rd_update(struct ope_hw *ope_hw_info,
 	CAM_DBG(CAM_OPE, "req_idx = %d req_id = %lld KMDbuf %x offset %d",
 		req_idx, ope_request->request_id,
 		kmd_buf, prepare->kmd_buf_offset);
-	bus_rd_ctx = &bus_rd->bus_rd_ctx[ctx_id];
+	bus_rd_ctx = bus_rd->bus_rd_ctx[ctx_id];
 	io_port_info = &bus_rd_ctx->io_port_info;
 	rd_reg = ope_hw_info->bus_rd_reg;
 	rd_reg_val = ope_hw_info->bus_rd_reg_val;
-
 	io_buf = ope_request->io_buf[batch_idx][io_idx];
 
+	CAM_DBG(CAM_OPE,
+		"req_idx = %d req_id = %lld KMDbuf 0x%x offset %d rsc %d",
+		req_idx, ope_request->request_id,
+		kmd_buf, prepare->kmd_buf_offset,
+		io_buf->resource_type);
 	CAM_DBG(CAM_OPE, "batch:%d iobuf:%d direction:%d",
 		batch_idx, io_idx, io_buf->direction);
 	io_port_cdm =
@@ -307,20 +311,15 @@ static uint32_t *cam_ope_bus_rd_update(struct ope_hw *ope_hw_info,
 				sizeof(temp));
 			CAM_DBG(CAM_OPE, "b:%d io:%d p:%d s:%d",
 				batch_idx, io_idx, k, l);
-			for (m = 0; m < count; m++)
-				CAM_DBG(CAM_OPE, "%d:temp:%x",
-					m, temp_reg[m]);
+			for (m = 0; m < count; m += 2)
+				CAM_DBG(CAM_OPE, "%d: off: 0x%x val: 0x%x",
+					m, temp_reg[m], temp_reg[m+1]);
 			CAM_DBG(CAM_OPE, "kmd_buf:%x offset:%d",
-			kmd_buf, prepare->kmd_buf_offset);
-			CAM_DBG(CAM_OPE, "%x count: %d size:%d",
-				 temp_reg, count, header_size);
-			CAM_DBG(CAM_OPE, "RD cmdbufs:%d off:%d",
-			io_port_cdm->num_s_cmd_bufs[l],
-			io_port_cdm->s_cdm_info[l][idx].offset);
-			CAM_DBG(CAM_OPE, "len:%d",
-			io_port_cdm->s_cdm_info[l][idx].len);
-			CAM_DBG(CAM_OPE, "b:%d io:%d p:%d s:%d",
-				batch_idx, io_idx, k, l);
+				kmd_buf, prepare->kmd_buf_offset);
+			CAM_DBG(CAM_OPE, "RD cmdbufs:%d off:%d len %d",
+				io_port_cdm->num_s_cmd_bufs[l],
+				io_port_cdm->s_cdm_info[l][idx].offset,
+				io_port_cdm->s_cdm_info[l][idx].len);
 			count = 0;
 		}
 	}
@@ -368,12 +367,13 @@ static uint32_t *cam_ope_bus_rm_disable(struct ope_hw *ope_hw_info,
 	req_idx = prepare->req_idx;
 	cdm_ops = ctx_data->ope_cdm.cdm_ops;
 
-	bus_rd_ctx = &bus_rd->bus_rd_ctx[ctx_id];
+	bus_rd_ctx = bus_rd->bus_rd_ctx[ctx_id];
 	io_port_cdm_batch = &bus_rd_ctx->io_port_cdm_batch;
 	rd_reg = ope_hw_info->bus_rd_reg;
 
-	CAM_DBG(CAM_OPE, "kmd_buf = %x req_idx = %d offset = %d",
-		kmd_buf, req_idx, prepare->kmd_buf_offset);
+	CAM_DBG(CAM_OPE,
+		"kmd_buf = 0x%x req_idx = %d offset = %d rd_idx %d b %d",
+		kmd_buf, req_idx, prepare->kmd_buf_offset, rm_idx, batch_idx);
 
 	io_port_cdm =
 		&bus_rd_ctx->io_port_cdm_batch.io_port_cdm[batch_idx];
@@ -402,20 +402,11 @@ static uint32_t *cam_ope_bus_rm_disable(struct ope_hw *ope_hw_info,
 		prepare->kmd_buf_offset += ((count + header_size) *
 			sizeof(temp));
 
-		CAM_DBG(CAM_OPE, "b:%d s:%d",
-			batch_idx, l);
-		CAM_DBG(CAM_OPE, "kmdbuf:%x, offset:%d",
-			kmd_buf, prepare->kmd_buf_offset);
-		CAM_DBG(CAM_OPE, "count:%d temp_reg:%x",
-			count, temp_reg, header_size);
-		CAM_DBG(CAM_OPE, "header_size:%d", header_size);
-			CAM_DBG(CAM_OPE, "RD cmd bufs = %d",
+		CAM_DBG(CAM_OPE, "RD cmd bufs = %d",
 			io_port_cdm->num_s_cmd_bufs[l]);
-		CAM_DBG(CAM_OPE, "off:%d len:%d",
-			io_port_cdm->s_cdm_info[l][idx].offset,
+		CAM_DBG(CAM_OPE, "stripe %d off:%d len:%d",
+			l, io_port_cdm->s_cdm_info[l][idx].offset,
 			io_port_cdm->s_cdm_info[l][idx].len);
-		CAM_DBG(CAM_OPE, "b:%d s:%d",
-			batch_idx, l);
 		count = 0;
 	}
 
@@ -464,7 +455,7 @@ static int cam_ope_bus_rd_prepare(struct ope_hw *ope_hw_info,
 		req_idx, ope_request->request_id);
 	CAM_DBG(CAM_OPE, "KMD buf and offset = %x %d",
 		kmd_buf, prepare->kmd_buf_offset);
-	bus_rd_ctx = &bus_rd->bus_rd_ctx[ctx_id];
+	bus_rd_ctx = bus_rd->bus_rd_ctx[ctx_id];
 	io_port_cdm_batch =
 		&bus_rd_ctx->io_port_cdm_batch;
 	memset(io_port_cdm_batch, 0,
@@ -562,25 +553,15 @@ end:
 static int cam_ope_bus_rd_release(struct ope_hw *ope_hw_info,
 	int32_t ctx_id, void *data)
 {
-	int rc = 0, i;
-	struct ope_acquire_dev_info *in_acquire;
-	struct ope_bus_rd_ctx *bus_rd_ctx;
+	int rc = 0;
 
-	if (ctx_id < 0) {
+	if (ctx_id < 0 || ctx_id >= OPE_CTX_MAX) {
 		CAM_ERR(CAM_OPE, "Invalid data: %d", ctx_id);
 		return -EINVAL;
 	}
 
-	in_acquire = bus_rd->bus_rd_ctx[ctx_id].ope_acquire;
-	bus_rd->bus_rd_ctx[ctx_id].ope_acquire = NULL;
-	bus_rd_ctx = &bus_rd->bus_rd_ctx[ctx_id];
-	bus_rd_ctx->num_in_ports = 0;
-
-	for (i = 0; i < bus_rd_ctx->num_in_ports; i++) {
-		bus_rd_ctx->io_port_info.input_port_id[i] = 0;
-		bus_rd_ctx->io_port_info.input_format_type[i - 1] = 0;
-		bus_rd_ctx->io_port_info.pixel_pattern[i - 1] = 0;
-	}
+	vfree(bus_rd->bus_rd_ctx[ctx_id]);
+	bus_rd->bus_rd_ctx[ctx_id] = NULL;
 
 	return rc;
 }
@@ -597,15 +578,21 @@ static int cam_ope_bus_rd_acquire(struct ope_hw *ope_hw_info,
 	int in_port_idx;
 
 
-	if (ctx_id < 0 || !data || !ope_hw_info) {
+	if (ctx_id < 0 || !data || !ope_hw_info || ctx_id >= OPE_CTX_MAX) {
 		CAM_ERR(CAM_OPE, "Invalid data: %d %x %x",
 			ctx_id, data, ope_hw_info);
 		return -EINVAL;
 	}
 
-	bus_rd->bus_rd_ctx[ctx_id].ope_acquire = data;
+	bus_rd->bus_rd_ctx[ctx_id] = vzalloc(sizeof(struct ope_bus_rd_ctx));
+	if (!bus_rd->bus_rd_ctx[ctx_id]) {
+		CAM_ERR(CAM_OPE, "Out of memory");
+		return -ENOMEM;
+	}
+
+	bus_rd->bus_rd_ctx[ctx_id]->ope_acquire = data;
 	in_acquire = data;
-	bus_rd_ctx = &bus_rd->bus_rd_ctx[ctx_id];
+	bus_rd_ctx = bus_rd->bus_rd_ctx[ctx_id];
 	bus_rd_ctx->num_in_ports = in_acquire->num_in_res;
 	bus_rd_ctx->security_flag = in_acquire->secure_mode;
 	bus_rd_reg_val = ope_hw_info->bus_rd_reg_val;

+ 1 - 1
drivers/cam_ope/ope_hw_mgr/ope_hw/bus_rd/ope_bus_rd.h

@@ -132,7 +132,7 @@ struct ope_bus_rd_ctx {
 struct ope_bus_rd {
 	struct ope_hw *ope_hw_info;
 	struct ope_bus_in_port_to_rm in_port_to_rm[OPE_IN_RES_MAX];
-	struct ope_bus_rd_ctx bus_rd_ctx[OPE_CTX_MAX];
+	struct ope_bus_rd_ctx *bus_rd_ctx[OPE_CTX_MAX];
 	struct completion reset_complete;
 };
 #endif /* OPE_BUS_RD_H */

+ 13 - 28
drivers/cam_ope/ope_hw_mgr/ope_hw/bus_wr/ope_bus_wr.c

@@ -169,7 +169,7 @@ static uint32_t *cam_ope_bus_wr_update(struct ope_hw *ope_hw_info,
 	int batch_idx, int io_idx,
 	uint32_t *kmd_buf, uint32_t *num_stripes)
 {
-	int k, l, out_port_idx;
+	int k, l, m, out_port_idx;
 	uint32_t idx;
 	uint32_t num_wm_ports;
 	uint32_t comb_idx;
@@ -226,8 +226,8 @@ static uint32_t *cam_ope_bus_wr_update(struct ope_hw *ope_hw_info,
 		prepare->kmd_buf_offset);
 
 	io_buf = ope_request->io_buf[batch_idx][io_idx];
-	CAM_DBG(CAM_OPE, "batch = %d io buf num = %d dir = %d",
-		batch_idx, io_idx, io_buf->direction);
+	CAM_DBG(CAM_OPE, "batch = %d io buf num = %d dir = %d rsc %d",
+		batch_idx, io_idx, io_buf->direction, io_buf->resource_type);
 
 	io_port_cdm =
 		&bus_wr_ctx->io_port_cdm_batch.io_port_cdm[batch_idx];
@@ -335,19 +335,15 @@ static uint32_t *cam_ope_bus_wr_update(struct ope_hw *ope_hw_info,
 
 			CAM_DBG(CAM_OPE, "b:%d io:%d p:%d s:%d",
 				batch_idx, io_idx, k, l);
+			for (m = 0; m < count; m += 2)
+				CAM_DBG(CAM_OPE, "%d: off: 0x%x val: 0x%x",
+					m, temp_reg[m], temp_reg[m+1]);
 			CAM_DBG(CAM_OPE, "kmdbuf:%x, offset:%d",
 				kmd_buf, prepare->kmd_buf_offset);
-			CAM_DBG(CAM_OPE, "count:%d temp_reg:%x",
-				count, temp_reg, header_size);
-			CAM_DBG(CAM_OPE, "header_size:%d", header_size);
-
-			CAM_DBG(CAM_OPE, "WR cmd bufs = %d",
-				io_port_cdm->num_s_cmd_bufs[l]);
-			CAM_DBG(CAM_OPE, "off:%d len:%d",
+			CAM_DBG(CAM_OPE, "WR cmd bufs = %d off:%d len:%d",
+				io_port_cdm->num_s_cmd_bufs[l],
 				io_port_cdm->s_cdm_info[l][idx].offset,
 				io_port_cdm->s_cdm_info[l][idx].len);
-			CAM_DBG(CAM_OPE, "b:%d io:%d p:%d s:%d",
-				batch_idx, io_idx, k, l);
 			count = 0;
 		}
 	}
@@ -398,8 +394,9 @@ static uint32_t *cam_ope_bus_wm_disable(struct ope_hw *ope_hw_info,
 	io_port_cdm_batch = &bus_wr_ctx->io_port_cdm_batch;
 	wr_reg = ope_hw_info->bus_wr_reg;
 
-	CAM_DBG(CAM_OPE, "kmd_buf = %x req_idx = %d offset = %d",
-		kmd_buf, req_idx, prepare->kmd_buf_offset);
+	CAM_DBG(CAM_OPE,
+		"kmd_buf = %x req_idx = %d offset = %d out_idx %d b %d",
+		kmd_buf, req_idx, prepare->kmd_buf_offset, io_idx, batch_idx);
 
 	io_port_cdm =
 		&bus_wr_ctx->io_port_cdm_batch.io_port_cdm[batch_idx];
@@ -409,8 +406,6 @@ static uint32_t *cam_ope_bus_wm_disable(struct ope_hw *ope_hw_info,
 
 	for (k = 0; k < num_wm_ports; k++) {
 		for (l = 0; l < num_stripes; l++) {
-			CAM_DBG(CAM_OPE, "comb_idx = %d p_idx = %d s_idx = %d",
-				comb_idx, k, l);
 			/* frame level info */
 			/* stripe level info */
 			wm_port_id = out_port_to_wm->wm_port_id[comb_idx][k];
@@ -436,21 +431,11 @@ static uint32_t *cam_ope_bus_wm_disable(struct ope_hw *ope_hw_info,
 			prepare->kmd_buf_offset += ((count + header_size) *
 				sizeof(temp));
 
-			CAM_DBG(CAM_OPE, "b:%d io:%d p:%d s:%d",
-				batch_idx, io_idx, k, l);
-			CAM_DBG(CAM_OPE, "kmdbuf:%x, offset:%d",
-				kmd_buf, prepare->kmd_buf_offset);
-			CAM_DBG(CAM_OPE, "count:%d temp_reg:%x",
-				count, temp_reg, header_size);
-			CAM_DBG(CAM_OPE, "header_size:%d", header_size);
-
 			CAM_DBG(CAM_OPE, "WR cmd bufs = %d",
 				io_port_cdm->num_s_cmd_bufs[l]);
-			CAM_DBG(CAM_OPE, "off:%d len:%d",
-				io_port_cdm->s_cdm_info[l][idx].offset,
+			CAM_DBG(CAM_OPE, "s:%d off:%d len:%d",
+				l, io_port_cdm->s_cdm_info[l][idx].offset,
 				io_port_cdm->s_cdm_info[l][idx].len);
-			CAM_DBG(CAM_OPE, "b:%d io:%d p:%d s:%d",
-				batch_idx, io_idx, k, l);
 			count = 0;
 		}
 	}

+ 52 - 29
drivers/cam_ope/ope_hw_mgr/ope_hw/ope_core.c

@@ -427,7 +427,7 @@ static int dump_dmi_cmd(uint32_t print_idx,
 	return 0;
 }
 
-static int dump_frame_direct(uint32_t print_idx,
+static int dump_direct_cmd(uint32_t print_idx,
 	uint32_t *print_ptr,
 	struct ope_frame_process *frm_proc,
 	int batch_idx, int cmd_buf_idx)
@@ -569,7 +569,7 @@ static uint32_t *ope_create_frame_cmd_batch(struct cam_ope_hw_mgr *hw_mgr,
 				iova_addr,
 				frm_proc->cmd_buf[i][j].length);
 			print_ptr = (uint32_t *)cpu_addr;
-			dump_frame_direct(print_idx, print_ptr,
+			dump_direct_cmd(print_idx, print_ptr,
 				frm_proc, i, j);
 		} else {
 			num_dmi = frm_proc->cmd_buf[i][j].length /
@@ -581,21 +581,28 @@ static uint32_t *ope_create_frame_cmd_batch(struct cam_ope_hw_mgr *hw_mgr,
 				memcpy(temp, (const void *)print_ptr,
 					sizeof(struct cdm_dmi_cmd));
 				dmi_cmd = (struct cdm_dmi_cmd *)temp;
+				if (!dmi_cmd->addr) {
+					CAM_ERR(CAM_OPE, "Null dmi cmd addr");
+					return NULL;
+				}
+
 				kmd_buf = cdm_ops->cdm_write_dmi(
 					kmd_buf,
 					0, dmi_cmd->DMIAddr,
 					dmi_cmd->DMISel, dmi_cmd->addr,
 					dmi_cmd->length);
-				dump_dmi_cmd(print_idx,
-					print_ptr, dmi_cmd, temp);
+				if (hw_mgr->frame_dump_enable)
+					dump_dmi_cmd(print_idx,
+						print_ptr, dmi_cmd, temp);
 				print_ptr +=
 					sizeof(struct cdm_dmi_cmd) /
 					sizeof(uint32_t);
 			}
 			CAM_DBG(CAM_OPE, "Frame DB : In direct: X");
 		}
-		dump_frame_cmd(frm_proc, i, j,
-			iova_addr, kmd_buf, buf_len);
+		if (hw_mgr->frame_dump_enable)
+			dump_frame_cmd(frm_proc, i, j,
+				iova_addr, kmd_buf, buf_len);
 	}
 	return kmd_buf;
 
@@ -719,8 +726,9 @@ static uint32_t *ope_create_frame_cmd(struct cam_ope_hw_mgr *hw_mgr,
 					iova_addr,
 					frm_proc->cmd_buf[i][j].length);
 				print_ptr = (uint32_t *)cpu_addr;
-				dump_frame_direct(print_idx, print_ptr,
-					frm_proc, i, j);
+				if (hw_mgr->frame_dump_enable)
+					dump_direct_cmd(print_idx, print_ptr,
+						frm_proc, i, j);
 			} else {
 				num_dmi = frm_proc->cmd_buf[i][j].length /
 					sizeof(struct cdm_dmi_cmd);
@@ -731,21 +739,30 @@ static uint32_t *ope_create_frame_cmd(struct cam_ope_hw_mgr *hw_mgr,
 					memcpy(temp, (const void *)print_ptr,
 						sizeof(struct cdm_dmi_cmd));
 					dmi_cmd = (struct cdm_dmi_cmd *)temp;
+					if (!dmi_cmd->addr) {
+						CAM_ERR(CAM_OPE,
+							"Null dmi cmd addr");
+						return NULL;
+					}
+
 					kmd_buf = cdm_ops->cdm_write_dmi(
 						kmd_buf,
 						0, dmi_cmd->DMIAddr,
 						dmi_cmd->DMISel, dmi_cmd->addr,
 						dmi_cmd->length);
-					dump_dmi_cmd(print_idx,
-						print_ptr, dmi_cmd, temp);
+					if (hw_mgr->frame_dump_enable)
+						dump_dmi_cmd(print_idx,
+							print_ptr, dmi_cmd,
+							temp);
 					print_ptr +=
 						sizeof(struct cdm_dmi_cmd) /
 						sizeof(uint32_t);
 				}
 				CAM_DBG(CAM_OPE, "Frame DB : In direct: X");
 			}
-			dump_frame_cmd(frm_proc, i, j,
-				iova_addr, kmd_buf, buf_len);
+			if (hw_mgr->frame_dump_enable)
+				dump_frame_cmd(frm_proc, i, j,
+					iova_addr, kmd_buf, buf_len);
 		}
 	}
 	return kmd_buf;
@@ -817,15 +834,12 @@ static uint32_t *ope_create_stripe_cmd(struct cam_ope_hw_mgr *hw_mgr,
 				kmd_buf,
 				iova_addr,
 				frm_proc->cmd_buf[i][k].length);
-				print_ptr = (uint32_t *)cpu_addr;
-				CAM_DBG(CAM_OPE, "Stripe:%d direct:E",
-					stripe_idx);
-			for (print_idx = 0; print_idx <
-				frm_proc->cmd_buf[i][k].length / 4;
-				print_idx++) {
-				CAM_DBG(CAM_OPE, "%d: %x", print_idx,
-					print_ptr[print_idx]);
-			}
+			print_ptr = (uint32_t *)cpu_addr;
+			CAM_DBG(CAM_OPE, "Stripe:%d direct:E",
+				stripe_idx);
+			if (hw_mgr->frame_dump_enable)
+				dump_direct_cmd(print_idx, print_ptr,
+					frm_proc, i, k);
 			CAM_DBG(CAM_OPE, "Stripe:%d direct:X", stripe_idx);
 		} else if (frm_proc->cmd_buf[i][k].type ==
 			OPE_CMD_BUF_TYPE_INDIRECT) {
@@ -837,18 +851,25 @@ static uint32_t *ope_create_stripe_cmd(struct cam_ope_hw_mgr *hw_mgr,
 				memcpy(temp, (const void *)print_ptr,
 					sizeof(struct cdm_dmi_cmd));
 				dmi_cmd = (struct cdm_dmi_cmd *)temp;
+				if (!dmi_cmd->addr) {
+					CAM_ERR(CAM_OPE, "Null dmi cmd addr");
+					return NULL;
+				}
+
 				kmd_buf = cdm_ops->cdm_write_dmi(kmd_buf,
 					0, dmi_cmd->DMIAddr, dmi_cmd->DMISel,
 					dmi_cmd->addr, dmi_cmd->length);
-				dump_dmi_cmd(print_idx,
-					print_ptr, dmi_cmd, temp);
+				if (hw_mgr->frame_dump_enable)
+					dump_dmi_cmd(print_idx,
+						print_ptr, dmi_cmd, temp);
 				print_ptr += sizeof(struct cdm_dmi_cmd) /
 					sizeof(uint32_t);
 			}
 			CAM_DBG(CAM_OPE, "Stripe:%d Indirect:X", stripe_idx);
 		}
-		dump_stripe_cmd(frm_proc, stripe_idx, i, k,
-			iova_addr, kmd_buf, buf_len);
+		if (hw_mgr->frame_dump_enable)
+			dump_stripe_cmd(frm_proc, stripe_idx, i, k,
+				iova_addr, kmd_buf, buf_len);
 	}
 	return kmd_buf;
 }
@@ -1511,10 +1532,12 @@ static int cam_ope_dev_process_prepare(struct ope_hw *ope_hw, void *cmd_args)
 	if (rc)
 		goto end;
 
-	cam_ope_dev_create_kmd_buf(ope_dev_prepare_req->hw_mgr,
-		ope_dev_prepare_req->prepare_args,
-		ope_dev_prepare_req->ctx_data, ope_dev_prepare_req->req_idx,
-		ope_dev_prepare_req->kmd_buf_offset, ope_dev_prepare_req);
+	rc = cam_ope_dev_create_kmd_buf(ope_dev_prepare_req->hw_mgr,
+			ope_dev_prepare_req->prepare_args,
+			ope_dev_prepare_req->ctx_data,
+			ope_dev_prepare_req->req_idx,
+			ope_dev_prepare_req->kmd_buf_offset,
+			ope_dev_prepare_req);
 
 end:
 	return rc;

+ 1 - 0
drivers/cam_ope/ope_hw_mgr/ope_hw/ope_dev.c

@@ -80,6 +80,7 @@ static int cam_ope_init_hw_version(struct cam_hw_soc_info *soc_info,
 	ope_hw_100.top_reg->base = core_info->ope_hw_info->ope_top_base;
 	ope_hw_100.bus_rd_reg->base = core_info->ope_hw_info->ope_bus_rd_base;
 	ope_hw_100.bus_wr_reg->base = core_info->ope_hw_info->ope_bus_wr_base;
+	ope_hw_100.pp_reg->base = core_info->ope_hw_info->ope_pp_base;
 
 	return rc;
 }

+ 15 - 0
drivers/cam_ope/ope_hw_mgr/ope_hw/ope_hw.h

@@ -14,6 +14,7 @@
 
 #define MAX_RD_CLIENTS   2
 #define MAX_WR_CLIENTS   8
+#define MAX_PP_CLIENTS   29
 
 #define OPE_CDM_BASE     0x0
 #define OPE_TOP_BASE     0x1
@@ -386,6 +387,18 @@ struct cam_ope_debug_register {
 	uint32_t offset;
 };
 
+struct cam_ope_bus_pp_client_reg {
+	uint32_t hw_status;
+};
+
+struct cam_ope_pp_reg {
+	void *base;
+	uint32_t offset;
+
+	uint32_t num_clients;
+	struct cam_ope_bus_pp_client_reg pp_clients[MAX_PP_CLIENTS];
+};
+
 struct ope_hw {
 	struct cam_ope_top_reg        *top_reg;
 	struct cam_ope_top_reg_val    *top_reg_val;
@@ -400,6 +413,8 @@ struct ope_hw {
 	struct cam_ope_qos_reg_val    *qos_reg_val;
 
 	struct cam_ope_common         *common;
+
+	struct cam_ope_pp_reg        *pp_reg;
 };
 
 struct hw_version_reg {

+ 96 - 0
drivers/cam_ope/ope_hw_mgr/ope_hw/ope_hw_100.h

@@ -554,6 +554,101 @@ static struct cam_ope_bus_wr_reg_val ope_bus_wr_reg_val = {
 		},
 	},
 };
+
+static struct cam_ope_pp_reg ope_pp_reg = {
+	.offset = 0x800,
+	.num_clients = MAX_PP_CLIENTS,
+	.pp_clients = {
+		{
+			.hw_status = 0x4,
+		},
+		{
+			.hw_status = 0x204,
+		},
+		{
+			.hw_status = 0x404,
+		},
+		{
+			.hw_status = 0x604,
+		},
+		{
+			.hw_status = 0x804,
+		},
+		{
+			.hw_status = 0xA04,
+		},
+		{
+			.hw_status = 0xC04,
+		},
+		{
+			.hw_status = 0xE04,
+		},
+		{
+			.hw_status = 0x1004,
+		},
+		{
+			.hw_status = 0x1204,
+		},
+		{
+			.hw_status = 0x1404,
+		},
+		{
+			.hw_status = 0x1604,
+		},
+		{
+			.hw_status = 0x1804,
+		},
+		{
+			.hw_status = 0x1A04,
+		},
+		{
+			.hw_status = 0x1C04,
+		},
+		{
+			.hw_status = 0x1E04,
+		},
+		{
+			.hw_status = 0x2204,
+		},
+		{
+			.hw_status = 0x2604,
+		},
+		{
+			.hw_status = 0x2804,
+		},
+		{
+			.hw_status = 0x2A04,
+		},
+		{
+			.hw_status = 0x2C04,
+		},
+		{
+			.hw_status = 0x2E04,
+		},
+		{
+			.hw_status = 0x3004,
+		},
+		{
+			.hw_status = 0x3204,
+		},
+		{
+			.hw_status = 0x3404,
+		},
+		{
+			.hw_status = 0x3604,
+		},
+		{
+			.hw_status = 0x3804,
+		},
+		{
+			.hw_status = 0x3A04,
+		},
+		{
+			.hw_status = 0x3C04,
+		},
+	},
+};
+
 static struct ope_hw ope_hw_100 = {
 	.top_reg     = &ope_top_reg,
 	.top_reg_val = &ope_top_reg_val,
@@ -561,6 +656,7 @@ static struct ope_hw ope_hw_100 = {
 	.bus_rd_reg_val  = &ope_bus_rd_reg_val,
 	.bus_wr_reg  = &ope_bus_wr_reg,
 	.bus_wr_reg_val  = &ope_bus_wr_reg_val,
+	.pp_reg  = &ope_pp_reg,
 };
 
 #endif /* CAM_OPE_HW_100_H */

+ 76 - 21
drivers/cam_ope/ope_hw_mgr/ope_hw/top/ope_top.c

@@ -50,6 +50,7 @@ static int cam_ope_top_reset(struct ope_hw *ope_hw_info,
 	struct cam_ope_top_reg *top_reg;
 	struct cam_ope_top_reg_val *top_reg_val;
 	uint32_t irq_mask, irq_status;
+	unsigned long flags;
 
 	if (!ope_hw_info) {
 		CAM_ERR(CAM_OPE, "Invalid ope_hw_info");
@@ -72,21 +73,37 @@ static int cam_ope_top_reset(struct ope_hw *ope_hw_info,
 
 	rc = wait_for_completion_timeout(
 			&ope_top_info.reset_complete,
-			msecs_to_jiffies(30));
+			msecs_to_jiffies(60));
 
 	cam_io_w_mb(top_reg_val->debug_cfg_val,
 		top_reg->base + top_reg->debug_cfg);
 
 	if (!rc || rc < 0) {
-		CAM_ERR(CAM_OPE, "reset error result = %d", rc);
-		irq_mask = cam_io_r_mb(ope_hw_info->top_reg->base +
-			top_reg->irq_mask);
-		irq_status = cam_io_r_mb(ope_hw_info->top_reg->base +
-			top_reg->irq_status);
-		CAM_ERR(CAM_OPE, "irq mask 0x%x irq status 0x%x",
-			irq_mask, irq_status);
-		cam_ope_top_dump_debug_reg(ope_hw_info);
-		rc = -ETIMEDOUT;
+		spin_lock_irqsave(&ope_top_info.hw_lock, flags);
+		if (!completion_done(&ope_top_info.reset_complete)) {
+			CAM_DBG(CAM_OPE,
+				"IRQ delayed, checking the status registers");
+			irq_mask = cam_io_r_mb(ope_hw_info->top_reg->base +
+				top_reg->irq_mask);
+			irq_status = cam_io_r_mb(ope_hw_info->top_reg->base +
+				top_reg->irq_status);
+			if (irq_status & top_reg_val->rst_done) {
+				CAM_DBG(CAM_OPE, "ope reset done");
+				cam_io_w_mb(irq_status,
+					top_reg->base + top_reg->irq_clear);
+				cam_io_w_mb(top_reg_val->irq_set_clear,
+					top_reg->base + top_reg->irq_cmd);
+			} else {
+				CAM_ERR(CAM_OPE,
+					"irq mask 0x%x irq status 0x%x",
+					irq_mask, irq_status);
+				cam_ope_top_dump_debug_reg(ope_hw_info);
+				rc = -ETIMEDOUT;
+			}
+		} else {
+			rc = 0;
+		}
+		spin_unlock_irqrestore(&ope_top_info.hw_lock, flags);
 	} else {
 		rc = 0;
 	}
@@ -137,6 +154,7 @@ static int cam_ope_top_init(struct ope_hw *ope_hw_info,
 	struct cam_ope_top_reg_val *top_reg_val;
 	struct cam_ope_dev_init *dev_init = data;
 	uint32_t irq_mask, irq_status;
+	unsigned long flags;
 
 	if (!ope_hw_info) {
 		CAM_ERR(CAM_OPE, "Invalid ope_hw_info");
@@ -160,25 +178,41 @@ static int cam_ope_top_init(struct ope_hw *ope_hw_info,
 
 	rc = wait_for_completion_timeout(
 			&ope_top_info.reset_complete,
-			msecs_to_jiffies(30));
+			msecs_to_jiffies(60));
 
 	cam_io_w_mb(top_reg_val->debug_cfg_val,
 		top_reg->base + top_reg->debug_cfg);
 
 	if (!rc || rc < 0) {
-		CAM_ERR(CAM_OPE, "reset error result = %d", rc);
-		irq_mask = cam_io_r_mb(ope_hw_info->top_reg->base +
-			top_reg->irq_mask);
-		irq_status = cam_io_r_mb(ope_hw_info->top_reg->base +
-			top_reg->irq_status);
-		CAM_ERR(CAM_OPE, "irq mask 0x%x irq status 0x%x",
-			irq_mask, irq_status);
-		cam_ope_top_dump_debug_reg(ope_hw_info);
-		rc = -ETIMEDOUT;
+		spin_lock_irqsave(&ope_top_info.hw_lock, flags);
+		if (!completion_done(&ope_top_info.reset_complete)) {
+			CAM_DBG(CAM_OPE,
+				"IRQ delayed, checking the status registers");
+			irq_mask = cam_io_r_mb(ope_hw_info->top_reg->base +
+				top_reg->irq_mask);
+			irq_status = cam_io_r_mb(ope_hw_info->top_reg->base +
+				top_reg->irq_status);
+			if (irq_status & top_reg_val->rst_done) {
+				CAM_DBG(CAM_OPE, "ope reset done");
+				cam_io_w_mb(irq_status,
+					top_reg->base + top_reg->irq_clear);
+				cam_io_w_mb(top_reg_val->irq_set_clear,
+					top_reg->base + top_reg->irq_cmd);
+			} else {
+				CAM_ERR(CAM_OPE,
+					"irq mask 0x%x irq status 0x%x",
+					irq_mask, irq_status);
+				cam_ope_top_dump_debug_reg(ope_hw_info);
+				rc = -ETIMEDOUT;
+			}
+		} else {
+			CAM_DBG(CAM_OPE, "reset done");
+			rc = 0;
+		}
+		spin_unlock_irqrestore(&ope_top_info.hw_lock, flags);
 	} else {
 		rc = 0;
 	}
-
 	/* enable interrupt mask */
 	cam_io_w_mb(top_reg_val->irq_mask,
 		ope_hw_info->top_reg->base + top_reg->irq_mask);
@@ -197,6 +231,7 @@ static int cam_ope_top_probe(struct ope_hw *ope_hw_info,
 	}
 
 	ope_top_info.ope_hw_info = ope_hw_info;
+	spin_lock_init(&ope_top_info.hw_lock);
 
 	return rc;
 }
@@ -207,9 +242,12 @@ static int cam_ope_top_isr(struct ope_hw *ope_hw_info,
 	int rc = 0;
 	uint32_t irq_status;
 	uint32_t violation_status;
+	uint32_t pp_hw_status = 0;
 	struct cam_ope_top_reg *top_reg;
 	struct cam_ope_top_reg_val *top_reg_val;
+	struct cam_ope_pp_reg *pp_reg;
 	struct cam_ope_irq_data *irq_data = data;
+	int i;
 
 	if (!ope_hw_info) {
 		CAM_ERR(CAM_OPE, "Invalid ope_hw_info");
@@ -218,7 +256,9 @@ static int cam_ope_top_isr(struct ope_hw *ope_hw_info,
 
 	top_reg = ope_hw_info->top_reg;
 	top_reg_val = ope_hw_info->top_reg_val;
+	pp_reg = ope_hw_info->pp_reg;
 
+	spin_lock(&ope_top_info.hw_lock);
 	/* Read and Clear Top Interrupt status */
 	irq_status = cam_io_r_mb(top_reg->base + top_reg->irq_status);
 	cam_io_w_mb(irq_status,
@@ -237,7 +277,22 @@ static int cam_ope_top_isr(struct ope_hw *ope_hw_info,
 			top_reg->violation_status);
 		irq_data->error = 1;
 		CAM_ERR(CAM_OPE, "ope violation: %x", violation_status);
+
+		for (i = 0; i < pp_reg->num_clients ; i++) {
+			pp_hw_status = 0;
+			pp_hw_status =
+				cam_io_r_mb(pp_reg->base +
+					pp_reg->pp_clients[i]
+						.hw_status);
+
+			if (pp_hw_status)
+				CAM_ERR(CAM_OPE,
+					"ope pp hw_status offset 0x%x val 0x%x",
+					pp_reg->pp_clients[i].hw_status,
+					pp_hw_status);
+		}
 	}
+	spin_unlock(&ope_top_info.hw_lock);
 
 	return rc;
 }

+ 2 - 0
drivers/cam_ope/ope_hw_mgr/ope_hw/top/ope_top.h

@@ -33,11 +33,13 @@ struct ope_top_ctx {
  * @top_ctx:        OPE top context
  * @reset_complete: Reset complete flag
  * @ope_mutex:      OPE hardware mutex
+ * @hw_lock:        OPE hardware spinlock
  */
 struct ope_top {
 	struct ope_hw *ope_hw_info;
 	struct ope_top_ctx top_ctx[OPE_CTX_MAX];
 	struct completion reset_complete;
 	struct mutex      ope_hw_mutex;
+	spinlock_t        hw_lock;
 };
 #endif /* OPE_TOP_H */