فهرست منبع

msm: camera: ope: Add fixes for probe, bus read and req_timer

As we are accessing hw version register during probe so calling
cpas_start and cpas_stop during probe.
Disabling the read clients which are not enabled for the request.
Resetting the req_timer when we receive the request from UMD.

CRs-Fixed: 2594541
Change-Id: I4a739fedbb498bd0c6b5b1e4cef38de3e4c722ed
Signed-off-by: Rishabh Jain <[email protected]>
Rishabh Jain 5 سال پیش
والد
کامیت
bd1e6c2420

+ 1 - 2
drivers/cam_ope/ope_hw_mgr/cam_ope_hw_mgr.c

@@ -2544,7 +2544,7 @@ static int cam_ope_mgr_prepare_hw_update(void *hw_priv,
 		return -EINVAL;
 	}
 	set_bit(request_idx, ctx_data->bitmap);
-
+	cam_ope_req_timer_reset(ctx_data);
 	ctx_data->req_list[request_idx] =
 		kzalloc(sizeof(struct cam_ope_request), GFP_KERNEL);
 	if (!ctx_data->req_list[request_idx]) {
@@ -2718,7 +2718,6 @@ static int cam_ope_mgr_config_hw(void *hw_priv, void *hw_config_args)
 
 	CAM_DBG(CAM_OPE, "req_id %llu, io config", ope_req->request_id);
 
-	cam_ope_req_timer_modify(ctx_data, 200);
 	mutex_unlock(&ctx_data->ctx_mutex);
 	mutex_unlock(&hw_mgr->hw_mgr_mutex);
 

+ 144 - 2
drivers/cam_ope/ope_hw_mgr/ope_hw/bus_rd/ope_bus_rd.c

@@ -82,9 +82,42 @@ static int cam_ope_bus_rd_combo_idx(uint32_t format)
 	return rc;
 }
 
+static int cam_ope_bus_is_rm_enabled(
+	struct cam_ope_request *ope_request,
+	uint32_t batch_idx,
+	uint32_t rm_id)
+{
+	int i, k;
+	int32_t combo_idx;
+	struct ope_io_buf *io_buf;
+	struct ope_bus_in_port_to_rm *in_port_to_rm;
+
+	if (batch_idx >= OPE_MAX_BATCH_SIZE) {
+		CAM_ERR(CAM_OPE, "Invalid batch idx: %d", batch_idx);
+		return -EINVAL;
+	}
+
+	for (i = 0; i < ope_request->num_io_bufs[batch_idx]; i++) {
+		io_buf = &ope_request->io_buf[batch_idx][i];
+		if (io_buf->direction != CAM_BUF_INPUT)
+			continue;
+		in_port_to_rm =
+			&bus_rd->in_port_to_rm[io_buf->resource_type - 1];
+		combo_idx = cam_ope_bus_rd_combo_idx(io_buf->format);
+		for (k = 0; k < io_buf->num_planes; k++) {
+			if (rm_id ==
+				in_port_to_rm->rm_port_id[combo_idx][k])
+				return true;
+		}
+	}
+
+	return false;
+}
+
 static uint32_t *cam_ope_bus_rd_update(struct ope_hw *ope_hw_info,
 	int32_t ctx_id, uint32_t *kmd_buf, int batch_idx,
-	int io_idx, struct cam_ope_dev_prepare_req *prepare)
+	int io_idx, struct cam_ope_dev_prepare_req *prepare,
+	int32_t *num_stripes)
 {
 	int k, l, m;
 	uint32_t idx;
@@ -154,6 +187,7 @@ static uint32_t *cam_ope_bus_rd_update(struct ope_hw *ope_hw_info,
 
 	for (k = 0; k < io_buf->num_planes; k++) {
 		for (l = 0; l < io_buf->num_stripes[k]; l++) {
+			*num_stripes = io_buf->num_stripes[k];
 			stripe_io = &io_buf->s_io[k][l];
 			rsc_type = io_buf->resource_type - 1;
 			/* frame level info */
@@ -259,6 +293,97 @@ static uint32_t *cam_ope_bus_rd_update(struct ope_hw *ope_hw_info,
 	return kmd_buf;
 }
 
+static uint32_t *cam_ope_bus_rm_disable(struct ope_hw *ope_hw_info,
+	int32_t ctx_id, struct cam_ope_dev_prepare_req *prepare,
+	int batch_idx, int rm_idx,
+	uint32_t *kmd_buf, uint32_t num_stripes)
+{
+	int l;
+	uint32_t idx;
+	uint32_t req_idx;
+	uint32_t temp_reg[128];
+	uint32_t count = 0;
+	uint32_t temp = 0;
+	uint32_t header_size;
+	struct cam_ope_ctx *ctx_data;
+	struct ope_bus_rd_ctx *bus_rd_ctx;
+	struct cam_ope_bus_rd_reg *rd_reg;
+	struct cam_ope_bus_rd_client_reg *rd_reg_client;
+	struct ope_bus_rd_io_port_cdm_batch *io_port_cdm_batch;
+	struct ope_bus_rd_io_port_cdm_info *io_port_cdm;
+	struct cam_cdm_utils_ops *cdm_ops;
+
+
+	if (ctx_id < 0 || !prepare) {
+		CAM_ERR(CAM_OPE, "Invalid data: %d %x", ctx_id, prepare);
+		return NULL;
+	}
+
+	if (batch_idx >= OPE_MAX_BATCH_SIZE) {
+		CAM_ERR(CAM_OPE, "Invalid batch idx: %d", batch_idx);
+		return NULL;
+	}
+
+	ctx_data = prepare->ctx_data;
+	req_idx = prepare->req_idx;
+	cdm_ops = ctx_data->ope_cdm.cdm_ops;
+
+	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);
+
+	io_port_cdm =
+		&bus_rd_ctx->io_port_cdm_batch.io_port_cdm[batch_idx];
+
+	for (l = 0; l < num_stripes; l++) {
+		/* stripe level info */
+		rd_reg_client = &rd_reg->rd_clients[rm_idx];
+
+		/* Core cfg: enable, Mode */
+		temp_reg[count++] = rd_reg->offset +
+			rd_reg_client->core_cfg;
+		temp_reg[count++] = 0;
+
+		header_size = cdm_ops->cdm_get_cmd_header_size(
+			CAM_CDM_CMD_REG_RANDOM);
+		idx = io_port_cdm->num_s_cmd_bufs[l];
+		io_port_cdm->s_cdm_info[l][idx].len =
+			sizeof(temp) * (count + header_size);
+		io_port_cdm->s_cdm_info[l][idx].offset =
+			prepare->kmd_buf_offset;
+		io_port_cdm->s_cdm_info[l][idx].addr = kmd_buf;
+		io_port_cdm->num_s_cmd_bufs[l]++;
+
+		kmd_buf = cdm_ops->cdm_write_regrandom(
+			kmd_buf, count/2, temp_reg);
+		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",
+			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,
+			io_port_cdm->s_cdm_info[l][idx].len);
+		CAM_DBG(CAM_OPE, "b:%d s:%d",
+			batch_idx, l);
+		count = 0;
+	}
+
+	prepare->rd_cdm_batch = &bus_rd_ctx->io_port_cdm_batch;
+
+	return kmd_buf;
+}
+
 static int cam_ope_bus_rd_prepare(struct ope_hw *ope_hw_info,
 	int32_t ctx_id, void *data)
 {
@@ -269,6 +394,7 @@ static int cam_ope_bus_rd_prepare(struct ope_hw *ope_hw_info,
 	uint32_t temp_reg[32] = {0};
 	uint32_t header_size;
 	uint32_t *kmd_buf;
+	int is_rm_enabled;
 	struct cam_ope_dev_prepare_req *prepare;
 	struct cam_ope_ctx *ctx_data;
 	struct cam_ope_request *ope_request;
@@ -279,6 +405,7 @@ static int cam_ope_bus_rd_prepare(struct ope_hw *ope_hw_info,
 	struct ope_bus_rd_io_port_cdm_batch *io_port_cdm_batch;
 	struct ope_bus_rd_io_port_cdm_info *io_port_cdm;
 	struct cam_cdm_utils_ops *cdm_ops;
+	int32_t num_stripes;
 
 	if (ctx_id < 0 || !data) {
 		CAM_ERR(CAM_OPE, "Invalid data: %d %x", ctx_id, data);
@@ -323,7 +450,8 @@ static int cam_ope_bus_rd_prepare(struct ope_hw *ope_hw_info,
 			}
 
 			kmd_buf = cam_ope_bus_rd_update(ope_hw_info,
-				ctx_id, kmd_buf, i, j, prepare);
+				ctx_id, kmd_buf, i, j, prepare,
+				&num_stripes);
 			if (!kmd_buf) {
 				rc = -EINVAL;
 				goto end;
@@ -336,6 +464,20 @@ static int cam_ope_bus_rd_prepare(struct ope_hw *ope_hw_info,
 		goto end;
 	}
 
+	/* Disable RMs which are not enabled */
+	for (i = 0; i < ope_request->num_batch; i++) {
+		for (j = 0; j < rd_reg_val->num_clients; j++) {
+			is_rm_enabled = cam_ope_bus_is_rm_enabled(
+				ope_request, i, j);
+			if (is_rm_enabled)
+				continue;
+
+			kmd_buf = cam_ope_bus_rm_disable(ope_hw_info,
+				ctx_id, prepare, i, j,
+				kmd_buf, num_stripes);
+		}
+	}
+
 	/* Go command */
 	count = 0;
 	temp_reg[count++] = rd_reg->offset +

+ 28 - 7
drivers/cam_ope/ope_hw_mgr/ope_hw/ope_dev.c

@@ -114,6 +114,7 @@ int cam_ope_probe(struct platform_device *pdev)
 	int                                rc = 0;
 	uint32_t hw_idx;
 	struct cam_ope_dev_probe ope_probe;
+	struct cam_ope_cpas_vote cpas_vote;
 
 	of_property_read_u32(pdev->dev.of_node,
 		"cell-index", &hw_idx);
@@ -176,25 +177,45 @@ int cam_ope_probe(struct platform_device *pdev)
 		CAM_ERR(CAM_OPE, "failed to init_soc");
 		goto init_soc_failed;
 	}
+	core_info->hw_type = OPE_DEV_OPE;
+	core_info->hw_idx = hw_idx;
+	rc = cam_ope_register_cpas(&ope_dev->soc_info,
+		core_info, ope_dev_intf->hw_idx);
+	if (rc < 0)
+		goto register_cpas_failed;
 
 	rc = cam_ope_enable_soc_resources(&ope_dev->soc_info);
 	if (rc < 0) {
 		CAM_ERR(CAM_OPE, "enable soc resorce failed: %d", rc);
 		goto enable_soc_failed;
 	}
+	cpas_vote.ahb_vote.type = CAM_VOTE_ABSOLUTE;
+	cpas_vote.ahb_vote.vote.level = CAM_SVS_VOTE;
+	cpas_vote.axi_vote.num_paths = 1;
+	cpas_vote.axi_vote.axi_path[0].path_data_type =
+		CAM_AXI_PATH_DATA_OPE_WR_VID;
+	cpas_vote.axi_vote.axi_path[0].transac_type =
+		CAM_AXI_TRANSACTION_WRITE;
+	cpas_vote.axi_vote.axi_path[0].camnoc_bw =
+		CAM_CPAS_DEFAULT_AXI_BW;
+	cpas_vote.axi_vote.axi_path[0].mnoc_ab_bw =
+		CAM_CPAS_DEFAULT_AXI_BW;
+	cpas_vote.axi_vote.axi_path[0].mnoc_ib_bw =
+		CAM_CPAS_DEFAULT_AXI_BW;
+	cpas_vote.axi_vote.axi_path[0].ddr_ab_bw =
+		CAM_CPAS_DEFAULT_AXI_BW;
+	cpas_vote.axi_vote.axi_path[0].ddr_ib_bw =
+		CAM_CPAS_DEFAULT_AXI_BW;
+
+	rc = cam_cpas_start(core_info->cpas_handle,
+		&cpas_vote.ahb_vote, &cpas_vote.axi_vote);
 
 	rc = cam_ope_init_hw_version(&ope_dev->soc_info, ope_dev->core_info);
 	if (rc)
 		goto init_hw_failure;
 
-	core_info->hw_type = OPE_DEV_OPE;
-	core_info->hw_idx = hw_idx;
-	rc = cam_ope_register_cpas(&ope_dev->soc_info,
-		core_info, ope_dev_intf->hw_idx);
-	if (rc < 0)
-		goto register_cpas_failed;
-
 	cam_ope_disable_soc_resources(&ope_dev->soc_info, true);
+	cam_cpas_stop(core_info->cpas_handle);
 	ope_dev->hw_state = CAM_HW_STATE_POWER_DOWN;
 
 	ope_probe.hfi_en = ope_soc_info.hfi_en;