diff --git a/drivers/cam_ope/ope_hw_mgr/cam_ope_hw_mgr.c b/drivers/cam_ope/ope_hw_mgr/cam_ope_hw_mgr.c index 039ee0f42750..ebbd7a08ff1a 100644 --- a/drivers/cam_ope/ope_hw_mgr/cam_ope_hw_mgr.c +++ b/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); diff --git a/drivers/cam_ope/ope_hw_mgr/ope_hw/bus_rd/ope_bus_rd.c b/drivers/cam_ope/ope_hw_mgr/ope_hw/bus_rd/ope_bus_rd.c index 649f5084c027..346016d2aae9 100644 --- a/drivers/cam_ope/ope_hw_mgr/ope_hw/bus_rd/ope_bus_rd.c +++ b/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 + diff --git a/drivers/cam_ope/ope_hw_mgr/ope_hw/ope_dev.c b/drivers/cam_ope/ope_hw_mgr/ope_hw/ope_dev.c index 1230fea487af..6435777a4b3e 100644 --- a/drivers/cam_ope/ope_hw_mgr/ope_hw/ope_dev.c +++ b/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,17 +177,6 @@ int cam_ope_probe(struct platform_device *pdev) CAM_ERR(CAM_OPE, "failed to init_soc"); goto init_soc_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; - } - - 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, @@ -194,7 +184,38 @@ int cam_ope_probe(struct platform_device *pdev) 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; + 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;