소스 검색

Merge "msm: camera: isp: Disable TFE WM clients dynamically" into camera-kernel.lnx.7.0

Camera Software Integration 1 년 전
부모
커밋
698290dae8

+ 4 - 2
drivers/cam_isp/cam_isp_context.c

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

+ 5 - 1
drivers/cam_isp/isp_hw_mgr/cam_tfe_hw_mgr.c

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

+ 2 - 0
drivers/cam_isp/isp_hw_mgr/cam_tfe_hw_mgr.h

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

+ 84 - 3
drivers/cam_isp/isp_hw_mgr/hw_utils/cam_isp_packet_parser.c

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

+ 21 - 0
drivers/cam_isp/isp_hw_mgr/hw_utils/include/cam_isp_packet_parser.h

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

+ 2 - 0
drivers/cam_isp/isp_hw_mgr/include/cam_isp_hw_mgr_intf.h

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

+ 1 - 0
drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h

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

+ 68 - 0
drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe_bus.c

@@ -654,6 +654,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)
@@ -2182,6 +2183,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)
 {
@@ -2783,6 +2848,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);

+ 1 - 0
drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe_core.c

@@ -3440,6 +3440,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);