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 <risjai@codeaurora.org>
This commit is contained in:
Rishabh Jain 2019-11-30 13:55:01 +05:30 • committed by Trishansh Bhardwaj
commit bd1e6c2420
3 changed files with 173 additions and 11 deletions

View file

@ -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);

View file

@ -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 +

View file

@ -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;