msm: camera: isp: Disable/Enable SFE read masters dynamically
For dynamic switch use-cases, disable SFE RMs if they are not used. Enable them if there is a switch utilizing that RM. This is the HW recommendation for dynamic switch use-cases. CRs-Fixed: 2841729 Change-Id: I93732fddced02c4e375635143de3f122f37ef008 Signed-off-by: Karthik Anantha Ram <kartanan@codeaurora.org>
Este cometimento está contido em:

cometido por
Gerrit - the friendly Code Review server

ascendente
311380c961
cometimento
a5fbb956da
@@ -7217,6 +7217,93 @@ end:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cam_isp_blob_sfe_update_fetch_core_cfg(
|
||||
uint32_t blob_type,
|
||||
struct cam_isp_generic_blob_info *blob_info,
|
||||
struct cam_hw_prepare_update_args *prepare)
|
||||
{
|
||||
int rc;
|
||||
uint32_t used_bytes = 0, total_used_bytes = 0;
|
||||
uint32_t remain_size, res_id;
|
||||
uint32_t *cpu_addr = NULL;
|
||||
bool enable = true;
|
||||
struct cam_isp_hw_mgr_res *hw_mgr_res;
|
||||
struct cam_kmd_buf_info *kmd_buf_info;
|
||||
struct cam_ife_hw_mgr_ctx *ctx = NULL;
|
||||
|
||||
ctx = prepare->ctxt_to_hw_map;
|
||||
if (prepare->num_hw_update_entries + 1 >=
|
||||
prepare->max_hw_update_entries) {
|
||||
CAM_ERR(CAM_ISP, "Insufficient HW entries :%d",
|
||||
prepare->num_hw_update_entries);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
kmd_buf_info = blob_info->kmd_buf_info;
|
||||
list_for_each_entry(hw_mgr_res, &ctx->res_list_ife_in_rd, list) {
|
||||
if ((kmd_buf_info->used_bytes
|
||||
+ total_used_bytes) < kmd_buf_info->size) {
|
||||
remain_size = kmd_buf_info->size -
|
||||
(kmd_buf_info->used_bytes +
|
||||
total_used_bytes);
|
||||
} else {
|
||||
CAM_ERR(CAM_ISP,
|
||||
"No free kmd memory for base idx: %d",
|
||||
blob_info->base_info->idx);
|
||||
rc = -ENOMEM;
|
||||
return rc;
|
||||
}
|
||||
|
||||
cpu_addr = kmd_buf_info->cpu_addr +
|
||||
(kmd_buf_info->used_bytes / 4) +
|
||||
(total_used_bytes / 4);
|
||||
|
||||
res_id = hw_mgr_res->res_id;
|
||||
|
||||
/* check for active fetches */
|
||||
if ((ctx->ctx_config &
|
||||
CAM_IFE_CTX_CFG_DYNAMIC_SWITCH_ON) &&
|
||||
((res_id - CAM_ISP_SFE_IN_RD_0) >=
|
||||
ctx->sfe_info.scratch_config->curr_num_exp))
|
||||
enable = false;
|
||||
else
|
||||
enable = true;
|
||||
|
||||
cpu_addr = kmd_buf_info->cpu_addr +
|
||||
kmd_buf_info->used_bytes / 4 +
|
||||
total_used_bytes / 4;
|
||||
|
||||
CAM_DBG(CAM_ISP,
|
||||
"SFE:%u RM: %u res_id: 0x%x enable: %u num_exp: %u",
|
||||
blob_info->base_info->idx,
|
||||
(res_id - CAM_ISP_SFE_IN_RD_0), res_id, enable,
|
||||
ctx->sfe_info.scratch_config->curr_num_exp);
|
||||
|
||||
rc = cam_isp_add_cmd_buf_update(
|
||||
hw_mgr_res, blob_type,
|
||||
CAM_ISP_HW_CMD_RM_ENABLE_DISABLE,
|
||||
blob_info->base_info->idx,
|
||||
(void *)cpu_addr, remain_size,
|
||||
(void *)&enable, &used_bytes);
|
||||
if (rc < 0) {
|
||||
CAM_ERR(CAM_ISP,
|
||||
"Failed to dynamically %s SFE: %u RM: %u bytes_used: %u rc: %d",
|
||||
(enable ? "enable" : "disable"),
|
||||
blob_info->base_info->idx, res_id,
|
||||
used_bytes, rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
total_used_bytes += used_bytes;
|
||||
}
|
||||
|
||||
if (total_used_bytes)
|
||||
cam_ife_mgr_update_hw_entries_util(
|
||||
false, total_used_bytes, kmd_buf_info, prepare);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cam_isp_blob_hfr_update(
|
||||
uint32_t blob_type,
|
||||
struct cam_isp_generic_blob_info *blob_info,
|
||||
@@ -9042,8 +9129,16 @@ static int cam_sfe_packet_generic_blob_handler(void *user_data,
|
||||
}
|
||||
|
||||
mup_config = (struct cam_isp_mode_switch_info *)blob_data;
|
||||
ife_mgr_ctx->sfe_info.scratch_config->curr_num_exp =
|
||||
mup_config->num_expoures;
|
||||
if (ife_mgr_ctx->flags.is_sfe_shdr) {
|
||||
ife_mgr_ctx->sfe_info.scratch_config->curr_num_exp =
|
||||
mup_config->num_expoures;
|
||||
|
||||
rc = cam_isp_blob_sfe_update_fetch_core_cfg(
|
||||
blob_type, blob_info, prepare);
|
||||
if (rc)
|
||||
CAM_ERR(CAM_ISP,
|
||||
"SFE dynamic enable/disable for fetch failed");
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CAM_ISP_GENERIC_BLOB_TYPE_SFE_EXP_ORDER_CFG: {
|
||||
|
@@ -161,6 +161,7 @@ enum cam_isp_hw_cmd_type {
|
||||
CAM_ISP_HW_SFE_SYS_CACHE_WM_CONFIG,
|
||||
CAM_ISP_HW_SFE_SYS_CACHE_RM_CONFIG,
|
||||
CAM_ISP_HW_CMD_WM_BW_LIMIT_CONFIG,
|
||||
CAM_ISP_HW_CMD_RM_ENABLE_DISABLE,
|
||||
CAM_ISP_HW_CMD_MAX,
|
||||
};
|
||||
|
||||
|
@@ -345,6 +345,7 @@ int cam_sfe_process_cmd(void *hw_priv, uint32_t cmd_type,
|
||||
case CAM_ISP_HW_CMD_BUF_UPDATE_RM:
|
||||
case CAM_ISP_HW_CMD_FE_UPDATE_BUS_RD:
|
||||
case CAM_ISP_HW_SFE_SYS_CACHE_RM_CONFIG:
|
||||
case CAM_ISP_HW_CMD_RM_ENABLE_DISABLE:
|
||||
rc = core_info->sfe_bus_rd->hw_ops.process_cmd(
|
||||
core_info->sfe_bus_rd->bus_priv, cmd_type,
|
||||
cmd_args, arg_size);
|
||||
|
@@ -459,9 +459,9 @@ static int cam_sfe_bus_start_rm(struct cam_isp_resource_node *rm_res)
|
||||
rm_res->res_state = CAM_ISP_RESOURCE_STATE_STREAMING;
|
||||
|
||||
CAM_DBG(CAM_SFE,
|
||||
"Start SFE:%d RM:%d offset:0x%X en_cfg:0x%X width:%d height:%d",
|
||||
"Start SFE:%d RM:%d offset:0x%X width:%d height:%d",
|
||||
rm_data->common_data->core_index, rm_data->index,
|
||||
(uint32_t) rm_data->hw_regs->cfg, rm_data->en_cfg,
|
||||
(uint32_t) rm_data->hw_regs->cfg,
|
||||
rm_data->width, rm_data->height);
|
||||
CAM_DBG(CAM_SFE, "RM:%d pk_fmt:%d stride:%d", rm_data->index,
|
||||
rm_data->unpacker_cfg, rm_data->stride);
|
||||
@@ -1392,6 +1392,84 @@ skip_cache_cfg:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cam_sfe_bus_rd_update_rm_core_cfg(
|
||||
void *priv, void *cmd_args, uint32_t arg_size)
|
||||
{
|
||||
struct cam_sfe_bus_rd_priv *bus_priv;
|
||||
struct cam_isp_hw_get_cmd_update *cmd_update;
|
||||
struct cam_sfe_bus_rd_data *sfe_bus_rd_data = NULL;
|
||||
struct cam_sfe_bus_rd_rm_resource_data *rm_data = NULL;
|
||||
struct cam_cdm_utils_ops *cdm_util_ops;
|
||||
bool enable_disable = false;
|
||||
uint32_t *reg_val_pair;
|
||||
uint32_t num_regval_pairs = 0, i, j, size = 0;
|
||||
|
||||
bus_priv = (struct cam_sfe_bus_rd_priv *) priv;
|
||||
cmd_update = (struct cam_isp_hw_get_cmd_update *) cmd_args;
|
||||
enable_disable = *(bool *)cmd_update->data;
|
||||
|
||||
sfe_bus_rd_data = (struct cam_sfe_bus_rd_data *)
|
||||
cmd_update->res->res_priv;
|
||||
|
||||
if (!sfe_bus_rd_data) {
|
||||
CAM_ERR(CAM_SFE, "Invalid SFE rd data: %pK",
|
||||
sfe_bus_rd_data);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
cdm_util_ops = sfe_bus_rd_data->cdm_util_ops;
|
||||
if (!cdm_util_ops) {
|
||||
CAM_ERR(CAM_SFE, "Invalid cdm ops: %pK",
|
||||
cdm_util_ops);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
reg_val_pair = &sfe_bus_rd_data->common_data->io_buf_update[0];
|
||||
for (i = 0, j = 0; i < sfe_bus_rd_data->num_rm; i++) {
|
||||
if (j >= (MAX_REG_VAL_PAIR_SIZE - MAX_BUF_UPDATE_REG_NUM * 2)) {
|
||||
CAM_ERR(CAM_SFE,
|
||||
"reg_val_pair %d exceeds the array limit %lu",
|
||||
j, MAX_REG_VAL_PAIR_SIZE);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
rm_data = sfe_bus_rd_data->rm_res[i]->res_priv;
|
||||
CAM_SFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
|
||||
rm_data->hw_regs->cfg, enable_disable);
|
||||
CAM_DBG(CAM_SFE, "SFE:%d RM:%d cfg:0x%x",
|
||||
rm_data->common_data->core_index,
|
||||
rm_data->index, reg_val_pair[j-1]);
|
||||
}
|
||||
|
||||
num_regval_pairs = j / 2;
|
||||
if (num_regval_pairs) {
|
||||
size = cdm_util_ops->cdm_required_size_reg_random(
|
||||
num_regval_pairs);
|
||||
|
||||
/* cdm util returns dwords, need to convert to bytes */
|
||||
if ((size * 4) > cmd_update->cmd.size) {
|
||||
CAM_ERR(CAM_SFE,
|
||||
"Failed! Buf size:%d insufficient, expected size:%d",
|
||||
cmd_update->cmd.size, size);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
cdm_util_ops->cdm_write_regrandom(
|
||||
cmd_update->cmd.cmd_buf_addr, num_regval_pairs,
|
||||
reg_val_pair);
|
||||
|
||||
/* cdm util returns dwords, need to convert to bytes */
|
||||
cmd_update->cmd.used_bytes = size * 4;
|
||||
} else {
|
||||
cmd_update->cmd.used_bytes = 0;
|
||||
CAM_DBG(CAM_SFE,
|
||||
"No reg val pairs. num_rms: %u",
|
||||
sfe_bus_rd_data->num_rm);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cam_sfe_bus_init_hw(void *hw_priv,
|
||||
void *init_hw_args, uint32_t arg_size)
|
||||
{
|
||||
@@ -1495,6 +1573,9 @@ static int cam_sfe_bus_rd_process_cmd(
|
||||
case CAM_ISP_HW_SFE_SYS_CACHE_RM_CONFIG:
|
||||
rc = cam_sfe_bus_rd_cache_config(priv, cmd_args, arg_size);
|
||||
break;
|
||||
case CAM_ISP_HW_CMD_RM_ENABLE_DISABLE:
|
||||
rc = cam_sfe_bus_rd_update_rm_core_cfg(priv, cmd_args, arg_size);
|
||||
break;
|
||||
default:
|
||||
CAM_ERR_RATE_LIMIT(CAM_SFE,
|
||||
"Invalid SFE BUS RD command type: %d",
|
||||
|
Criar uma nova questão referindo esta
Bloquear um utilizador