msm: camera: isp: Disable TFE WM clients dynamically
This commit adds support to disable acquired TFE WM clients if the client is not configured. CRs-Fixed: 3531808 Change-Id: Ie3be423dfd2ab35031677563d66fd811090148fe Signed-off-by: Ayush Kumar <quic_ayushkr@quicinc.com>
Este cometimento está contido em:

cometido por
Alok Chauhan

ascendente
f31de7d3d0
cometimento
428c68409d
@@ -2431,11 +2431,13 @@ static int __cam_isp_ctx_handle_buf_done_for_request_verify_addr(
|
||||
continue;
|
||||
} else if (!req_isp->bubble_detected) {
|
||||
CAM_DBG(CAM_ISP,
|
||||
"Sync with success: req %lld res 0x%x fd 0x%x, ctx:%u link[0x%x]",
|
||||
"Sync with success: req %lld res 0x%x fd 0x%x, ctx %u res %s",
|
||||
req->request_id,
|
||||
req_isp->fence_map_out[j].resource_handle,
|
||||
req_isp->fence_map_out[j].sync_id,
|
||||
ctx->ctx_id, ctx->link_hdl);
|
||||
ctx->ctx_id,
|
||||
__cam_isp_resource_handle_id_to_type(ctx_isp->isp_device_type,
|
||||
req_isp->fence_map_out[j].resource_handle));
|
||||
|
||||
cam_smmu_buffer_tracker_buffer_putref(
|
||||
req_isp->fence_map_out[j].buffer_tracker);
|
||||
|
@@ -1011,6 +1011,7 @@ static int cam_tfe_hw_mgr_acquire_res_tfe_out_rdi(
|
||||
tfe_out_res->res_id = tfe_out_res_id;
|
||||
tfe_out_res->res_type = CAM_ISP_RESOURCE_TFE_OUT;
|
||||
tfe_in_res->num_children++;
|
||||
tfe_ctx->acquired_wm_mask |= (1 << out_port->res_id);
|
||||
|
||||
return 0;
|
||||
err:
|
||||
@@ -1104,6 +1105,7 @@ static int cam_tfe_hw_mgr_acquire_res_tfe_out_pixel(
|
||||
tfe_out_res->res_type = CAM_ISP_RESOURCE_TFE_OUT;
|
||||
tfe_out_res->res_id = out_port->res_id;
|
||||
tfe_in_res->num_children++;
|
||||
tfe_ctx->acquired_wm_mask |= (1 << out_port->res_id);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -4066,6 +4068,7 @@ static int cam_tfe_mgr_release_hw(void *hw_mgr_priv,
|
||||
ctx->tfe_bus_comp_grp = NULL;
|
||||
ctx->is_shdr = false;
|
||||
ctx->is_shdr_slave = false;
|
||||
ctx->acquired_wm_mask = 0;
|
||||
atomic_set(&ctx->overflow_pending, 0);
|
||||
|
||||
for (i = 0; i < ctx->last_submit_bl_cmd.bl_count; i++) {
|
||||
@@ -5129,7 +5132,6 @@ static int cam_tfe_mgr_prepare_hw_update(void *hw_mgr_priv,
|
||||
goto end;
|
||||
}
|
||||
|
||||
|
||||
/* get command buffers */
|
||||
if (ctx->base[i].split_id != CAM_ISP_HW_SPLIT_MAX) {
|
||||
rc = cam_tfe_add_command_buffers(prepare,
|
||||
@@ -5149,6 +5151,8 @@ static int cam_tfe_mgr_prepare_hw_update(void *hw_mgr_priv,
|
||||
sizeof(struct cam_isp_frame_header_info));
|
||||
frame_header_info.frame_header_enable = false;
|
||||
|
||||
prepare_hw_data->wm_bitmask = ctx->acquired_wm_mask;
|
||||
|
||||
/* get IO buffers */
|
||||
io_buf_info.frame_hdr = &frame_header_info;
|
||||
io_buf_info.scratch_check_cfg = &check_for_scratch;
|
||||
|
@@ -129,6 +129,7 @@ struct cam_tfe_cdm_user_data {
|
||||
* @try_recovery_cnt Retry count for overflow recovery
|
||||
* @current_mup Current MUP val
|
||||
* @recovery_req_id The request id on which overflow recovery happens
|
||||
* @acquired_wm_mask Bitmask of acquired out resource
|
||||
* @is_shdr Indicate if the usecase is SHDR
|
||||
* @is_shdr_slave Indicate whether context is slave in shdr usecase
|
||||
*/
|
||||
@@ -178,6 +179,7 @@ struct cam_tfe_hw_mgr_ctx {
|
||||
uint32_t current_mup;
|
||||
uint32_t try_recovery_cnt;
|
||||
uint64_t recovery_req_id;
|
||||
uint64_t acquired_wm_mask;
|
||||
enum cam_cdm_id cdm_id;
|
||||
bool is_shdr;
|
||||
bool is_shdr_slave;
|
||||
|
@@ -1123,7 +1123,7 @@ int cam_isp_add_io_buffers(struct cam_isp_io_buf_info *io_info)
|
||||
int rc = 0;
|
||||
struct cam_buf_io_cfg *io_cfg = NULL;
|
||||
struct cam_isp_hw_mgr_res *hw_mgr_res = NULL;
|
||||
uint32_t i;
|
||||
uint32_t i, j;
|
||||
uint32_t curr_used_bytes = 0;
|
||||
uint32_t bytes_updated = 0;
|
||||
struct cam_isp_resource_node *res = NULL;
|
||||
@@ -1132,6 +1132,8 @@ int cam_isp_add_io_buffers(struct cam_isp_io_buf_info *io_info)
|
||||
uint8_t max_out_res = 0;
|
||||
uint64_t *mc_cfg = NULL;
|
||||
uint32_t major_version = 0;
|
||||
struct cam_isp_prepare_hw_update_data *prepare_hw_data;
|
||||
uint64_t cfg_io_mask = 0, disabled_wm_mask = 0;
|
||||
|
||||
io_cfg = (struct cam_buf_io_cfg *) ((uint8_t *)
|
||||
&io_info->prepare->packet->payload +
|
||||
@@ -1158,6 +1160,7 @@ int cam_isp_add_io_buffers(struct cam_isp_io_buf_info *io_info)
|
||||
}
|
||||
}
|
||||
|
||||
prepare_hw_data = (struct cam_isp_prepare_hw_update_data *) io_info->prepare->priv;
|
||||
for (i = 0; i < io_info->prepare->packet->num_io_configs; i++) {
|
||||
|
||||
if (major_version == 3) {
|
||||
@@ -1192,6 +1195,8 @@ int cam_isp_add_io_buffers(struct cam_isp_io_buf_info *io_info)
|
||||
if (!res)
|
||||
continue;
|
||||
|
||||
cfg_io_mask |= (1 << (res->res_id & 0xFF));
|
||||
|
||||
rc = cam_isp_add_io_buffers_util(io_info, &io_cfg[i], res);
|
||||
if (rc) {
|
||||
CAM_ERR(CAM_ISP, "io_cfg[%d] add buf failed rc %d", i, rc);
|
||||
@@ -1214,9 +1219,25 @@ int cam_isp_add_io_buffers(struct cam_isp_io_buf_info *io_info)
|
||||
vfree(mc_cfg);
|
||||
}
|
||||
|
||||
disabled_wm_mask = (prepare_hw_data->wm_bitmask ^ cfg_io_mask);
|
||||
if ((io_info->base->hw_type == CAM_ISP_HW_TYPE_TFE) && disabled_wm_mask) {
|
||||
for (j = 0; j < io_info->out_max; j++) {
|
||||
rc = cam_isp_add_disable_wm_update(io_info->prepare,
|
||||
&io_info->res_list_isp_out[j],
|
||||
io_info->base->idx, io_info->kmd_buf_info,
|
||||
disabled_wm_mask,
|
||||
&io_info->kmd_buf_info->used_bytes);
|
||||
if (rc) {
|
||||
CAM_ERR_RATE_LIMIT(CAM_ISP, "Disable out res %d failed",
|
||||
j, rc);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bytes_updated = io_info->kmd_buf_info->used_bytes - curr_used_bytes;
|
||||
CAM_DBG(CAM_ISP, "io_cfg_used_bytes %d, fill_fence %d",
|
||||
bytes_updated, io_info->fill_fence);
|
||||
CAM_DBG(CAM_ISP, "io_cfg_used_bytes %d, fill_fence %d acuired mask %x cfg mask %x",
|
||||
bytes_updated, io_info->fill_fence, prepare_hw_data->wm_bitmask, cfg_io_mask);
|
||||
|
||||
if (bytes_updated) {
|
||||
/**
|
||||
@@ -1237,6 +1258,66 @@ err:
|
||||
return rc;
|
||||
}
|
||||
|
||||
int cam_isp_add_disable_wm_update(
|
||||
struct cam_hw_prepare_update_args *prepare,
|
||||
struct cam_isp_hw_mgr_res *isp_hw_res,
|
||||
uint32_t base_idx,
|
||||
struct cam_kmd_buf_info *kmd_buf_info,
|
||||
uint64_t wm_mask,
|
||||
uint32_t *io_cfg_used_bytes)
|
||||
{
|
||||
int rc = 0;
|
||||
struct cam_hw_intf *hw_intf;
|
||||
struct cam_isp_resource_node *res;
|
||||
struct cam_isp_hw_get_cmd_update wm_update;
|
||||
uint32_t kmd_buf_remain_size, i;
|
||||
|
||||
if (prepare->packet->header.request_id == 0)
|
||||
return 0;
|
||||
for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) {
|
||||
if (!isp_hw_res->hw_res[i])
|
||||
continue;
|
||||
hw_intf = isp_hw_res->hw_res[i]->hw_intf;
|
||||
res = isp_hw_res->hw_res[i];
|
||||
if (res->hw_intf->hw_idx != base_idx)
|
||||
continue;
|
||||
if (!(wm_mask & (1 << res->res_id))) {
|
||||
CAM_DBG(CAM_ISP, "No need to disable out res %d", res->res_id);
|
||||
continue;
|
||||
}
|
||||
if (kmd_buf_info->size > (kmd_buf_info->used_bytes +
|
||||
(*io_cfg_used_bytes))) {
|
||||
kmd_buf_remain_size = kmd_buf_info->size -
|
||||
(kmd_buf_info->used_bytes +
|
||||
(*io_cfg_used_bytes));
|
||||
} else {
|
||||
CAM_ERR(CAM_ISP, "no free mem %d %d", kmd_buf_info->size,
|
||||
kmd_buf_info->used_bytes + (*io_cfg_used_bytes));
|
||||
rc = -EINVAL;
|
||||
return rc;
|
||||
}
|
||||
wm_update.cmd.cmd_buf_addr = kmd_buf_info->cpu_addr +
|
||||
kmd_buf_info->used_bytes/4 + (*io_cfg_used_bytes)/4;
|
||||
wm_update.cmd.size = kmd_buf_remain_size;
|
||||
wm_update.cmd_type = CAM_ISP_HW_CMD_BUS_WM_DISABLE;
|
||||
wm_update.res = res;
|
||||
rc = res->hw_intf->hw_ops.process_cmd(
|
||||
res->hw_intf->hw_priv,
|
||||
CAM_ISP_HW_CMD_BUS_WM_DISABLE, &wm_update,
|
||||
sizeof(struct cam_isp_hw_get_cmd_update));
|
||||
if (rc) {
|
||||
CAM_ERR(CAM_ISP, "Diaable res %d failed split %d",
|
||||
res->res_id, i);
|
||||
return rc;
|
||||
}
|
||||
CAM_DBG(CAM_ISP,
|
||||
"Out res %d disable update added hw_id %d cdm_idx %d",
|
||||
res->res_id, res->hw_intf->hw_idx, base_idx);
|
||||
(*io_cfg_used_bytes) += wm_update.cmd.used_bytes;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
int cam_isp_add_reg_update(
|
||||
struct cam_hw_prepare_update_args *prepare,
|
||||
struct list_head *res_list_isp_src,
|
||||
|
@@ -278,6 +278,27 @@ int cam_isp_add_command_buffers(
|
||||
*/
|
||||
int cam_isp_add_io_buffers(struct cam_isp_io_buf_info *io_info);
|
||||
|
||||
/*
|
||||
* cam_isp_add_disable_wm_update()
|
||||
*
|
||||
* @brief Add disable wm command
|
||||
*
|
||||
* @prepare: Contain the packet and HW update variables
|
||||
* @isp_hw_res: Resource list for IFE/VFE out resource
|
||||
* @base_idx: Base or dev index of the IFE/VFE HW instance
|
||||
* @kmd_buf_info: Kmd buffer to store the change base command
|
||||
* @wm_mask Bit mask of unconfigured resource
|
||||
* @io_cfg_used_bytes IO cfg size used in bytes
|
||||
*
|
||||
*/
|
||||
int cam_isp_add_disable_wm_update(
|
||||
struct cam_hw_prepare_update_args *prepare,
|
||||
struct cam_isp_hw_mgr_res *isp_hw_res,
|
||||
uint32_t base_idx,
|
||||
struct cam_kmd_buf_info *kmd_buf_info,
|
||||
uint64_t wm_mask,
|
||||
uint32_t *io_cfg_used_bytes);
|
||||
|
||||
/*
|
||||
* cam_isp_add_reg_update()
|
||||
*
|
||||
|
@@ -348,6 +348,7 @@ struct cam_isp_fcg_config_info {
|
||||
* @packet: CSL packet from user mode driver
|
||||
* @mup_val: MUP value if configured
|
||||
* @num_exp: Num of exposures
|
||||
* @wm_bitmask: Bitmask of acquired out resource
|
||||
* @mup_en: Flag if dynamic sensor switch is enabled
|
||||
* @fcg_info: Track FCG config for further usage in config stage
|
||||
*
|
||||
@@ -370,6 +371,7 @@ struct cam_isp_prepare_hw_update_data {
|
||||
struct cam_kmd_buf_info kmd_cmd_buff_info;
|
||||
uint32_t mup_val;
|
||||
uint32_t num_exp;
|
||||
uint64_t wm_bitmask;
|
||||
bool mup_en;
|
||||
struct cam_isp_fcg_config_info fcg_info;
|
||||
};
|
||||
|
@@ -258,6 +258,7 @@ enum cam_isp_hw_cmd_type {
|
||||
CAM_ISP_HW_CMD_GET_SET_PRIM_SOF_TS_ADDR,
|
||||
CAM_ISP_HW_CMD_DYNAMIC_CLOCK_UPDATE,
|
||||
CAM_ISP_HW_CMD_SET_SYNC_HW_IDX,
|
||||
CAM_ISP_HW_CMD_BUS_WM_DISABLE,
|
||||
CAM_ISP_HW_CMD_MAX,
|
||||
};
|
||||
|
||||
|
@@ -653,6 +653,7 @@ static int cam_tfe_bus_acquire_rdi_wm(
|
||||
int pack_fmt = 0;
|
||||
int rdi_width = rsrc_data->common_data->rdi_width;
|
||||
int mode_cfg_shift = rsrc_data->common_data->mode_cfg_shift;
|
||||
|
||||
if (rdi_width == 64)
|
||||
pack_fmt = 0xa;
|
||||
else if (rdi_width == 128)
|
||||
@@ -2164,6 +2165,70 @@ end:
|
||||
|
||||
}
|
||||
|
||||
static int cam_tfe_bus_diable_wm(void *priv, void *cmd_args,
|
||||
uint32_t arg_size)
|
||||
{
|
||||
struct cam_tfe_bus_priv *bus_priv;
|
||||
struct cam_isp_hw_get_cmd_update *update_buf;
|
||||
struct cam_tfe_bus_tfe_out_data *tfe_out_data = NULL;
|
||||
struct cam_tfe_bus_wm_resource_data *wm_data = NULL;
|
||||
struct cam_cdm_utils_ops *cdm_util_ops = NULL;
|
||||
uint32_t *reg_val_pair;
|
||||
uint32_t num_regval_pairs = 0;
|
||||
uint32_t i, j, size = 0;
|
||||
|
||||
bus_priv = (struct cam_tfe_bus_priv *) priv;
|
||||
update_buf = (struct cam_isp_hw_get_cmd_update *) cmd_args;
|
||||
tfe_out_data = (struct cam_tfe_bus_tfe_out_data *) update_buf->res->res_priv;
|
||||
|
||||
if (!tfe_out_data || !(tfe_out_data->cdm_util_ops)) {
|
||||
CAM_ERR(CAM_ISP, "Failed! invalid data");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
cdm_util_ops = tfe_out_data->cdm_util_ops;
|
||||
|
||||
reg_val_pair = &tfe_out_data->common_data->io_buf_update[0];
|
||||
for (i = 0, j = 0; i < tfe_out_data->num_wm; i++) {
|
||||
if (j >= (MAX_REG_VAL_PAIR_SIZE - MAX_BUF_UPDATE_REG_NUM * 2)) {
|
||||
CAM_ERR(CAM_ISP,
|
||||
"reg_val_pair %d exceeds the array limit %zu",
|
||||
j, MAX_REG_VAL_PAIR_SIZE);
|
||||
return -ENOMEM;
|
||||
}
|
||||
wm_data = tfe_out_data->wm_res[i]->res_priv;
|
||||
|
||||
CAM_TFE_ADD_REG_VAL_PAIR(reg_val_pair, j, wm_data->hw_regs->cfg, 0);
|
||||
CAM_DBG(CAM_ISP, "WM:%d disabled cfg %x", wm_data->index, wm_data->hw_regs->cfg);
|
||||
}
|
||||
|
||||
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) > update_buf->cmd.size) {
|
||||
CAM_ERR(CAM_ISP,
|
||||
"Failed! Buf size:%d insufficient, expected size:%d",
|
||||
update_buf->cmd.size, size);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
cdm_util_ops->cdm_write_regrandom(
|
||||
update_buf->cmd.cmd_buf_addr,
|
||||
num_regval_pairs, reg_val_pair);
|
||||
|
||||
/* cdm util returns dwords, need to convert to bytes */
|
||||
update_buf->cmd.used_bytes = size * 4;
|
||||
} else {
|
||||
update_buf->cmd.used_bytes = 0;
|
||||
CAM_DBG(CAM_ISP, "No reg val pairs. num_wms: %u", tfe_out_data->num_wm);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cam_tfe_bus_update_wm(void *priv, void *cmd_args,
|
||||
uint32_t arg_size)
|
||||
{
|
||||
@@ -2753,6 +2818,9 @@ static int cam_tfe_bus_process_cmd(void *priv,
|
||||
done->last_consumed_addr = cam_tfe_bus_get_last_consumed_addr(
|
||||
bus_priv, done->resource_handle);
|
||||
break;
|
||||
case CAM_ISP_HW_CMD_BUS_WM_DISABLE:
|
||||
rc = cam_tfe_bus_diable_wm(priv, cmd_args, arg_size);
|
||||
break;
|
||||
default:
|
||||
CAM_ERR_RATE_LIMIT(CAM_ISP, "Invalid camif process command:%d",
|
||||
cmd_type);
|
||||
|
@@ -3439,6 +3439,7 @@ int cam_tfe_process_cmd(void *hw_priv, uint32_t cmd_type,
|
||||
case CAM_ISP_HW_CMD_IS_PDAF_RDI2_MUX_EN:
|
||||
case CAM_ISP_HW_CMD_WM_BW_LIMIT_CONFIG:
|
||||
case CAM_ISP_HW_CMD_GET_LAST_CONSUMED_ADDR:
|
||||
case CAM_ISP_HW_CMD_BUS_WM_DISABLE:
|
||||
rc = core_info->tfe_bus->hw_ops.process_cmd(
|
||||
core_info->tfe_bus->bus_priv, cmd_type, cmd_args,
|
||||
arg_size);
|
||||
|
Criar uma nova questão referindo esta
Bloquear um utilizador