1
0

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:
Ayush Kumar
2023-05-19 18:29:02 +05:30
cometido por Alok Chauhan
ascendente f31de7d3d0
cometimento 428c68409d
9 ficheiros modificados com 188 adições e 6 eliminações

Ver ficheiro

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

Ver ficheiro

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

Ver ficheiro

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

Ver ficheiro

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

Ver ficheiro

@@ -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()
*

Ver ficheiro

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

Ver ficheiro

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

Ver ficheiro

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

Ver ficheiro

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