فهرست منبع

msm: camera: tfe: Add support for TFE BW limiter

Add blob to allow userland to configure BW limter for TFE WMs.

CRs-Fixed: 3505174
Change-Id: I5c671cbcfa5557082c4ae5302471a2ece45294ab
Signed-off-by: Dharmender Sharma <[email protected]>
Signed-off-by: Yash Upadhyay <[email protected]>
Yash Upadhyay 2 سال پیش
والد
کامیت
c98bea4b04

+ 153 - 0
drivers/cam_isp/isp_hw_mgr/cam_tfe_hw_mgr.c

@@ -3887,6 +3887,137 @@ static int cam_isp_tfe_blob_clock_update(
 	return rc;
 }
 
+static int cam_isp_tfe_blob_bw_limit_update(
+	uint32_t                                   blob_type,
+	struct cam_isp_generic_blob_info          *blob_info,
+	struct cam_isp_tfe_out_rsrc_bw_limiter_config *bw_limit_cfg,
+	struct cam_hw_prepare_update_args         *prepare,
+	enum cam_isp_hw_type                       hw_type)
+{
+	struct cam_isp_tfe_wm_bw_limiter_config   *wm_bw_limit_cfg;
+	struct cam_kmd_buf_info               *kmd_buf_info;
+	struct cam_tfe_hw_mgr_ctx             *ctx = NULL;
+	struct cam_isp_hw_mgr_res             *hw_mgr_res;
+	uint32_t                               res_id_out, i;
+	uint32_t                               total_used_bytes = 0;
+	uint32_t                               kmd_buf_remain_size;
+	uint32_t                              *cmd_buf_addr;
+	uint32_t                               bytes_used = 0;
+	int                                    num_ent, rc = 0;
+
+	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 max: %d",
+			prepare->num_hw_update_entries,
+			prepare->max_hw_update_entries);
+		return -EINVAL;
+	}
+
+	kmd_buf_info = blob_info->kmd_buf_info;
+	for (i = 0; i < bw_limit_cfg->num_ports; i++) {
+		wm_bw_limit_cfg = &bw_limit_cfg->bw_limiter_config[i];
+		res_id_out = wm_bw_limit_cfg->res_type & 0xFF;
+
+		CAM_DBG(CAM_ISP, "%s BW limit config idx: %d port: 0x%x enable: %d [0x%x:0x%x]",
+			"TFE", i, wm_bw_limit_cfg->res_type, wm_bw_limit_cfg->enable_limiter,
+			wm_bw_limit_cfg->counter_limit[0], wm_bw_limit_cfg->counter_limit[1]);
+
+		if ((kmd_buf_info->used_bytes
+			+ total_used_bytes) < kmd_buf_info->size) {
+			kmd_buf_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;
+		}
+
+		cmd_buf_addr = kmd_buf_info->cpu_addr +
+			(kmd_buf_info->used_bytes / 4) +
+			(total_used_bytes / 4);
+
+		hw_mgr_res = &ctx->res_list_tfe_out[res_id_out];
+
+		rc = cam_isp_add_cmd_buf_update(
+			hw_mgr_res, blob_type,
+			CAM_ISP_HW_CMD_WM_BW_LIMIT_CONFIG,
+			blob_info->base_info->idx,
+			(void *)cmd_buf_addr,
+			kmd_buf_remain_size,
+			(void *)wm_bw_limit_cfg,
+			&bytes_used);
+		if (rc < 0) {
+			CAM_ERR(CAM_ISP,
+				"Failed to update %s BW limiter config for res:0x%x enable:%d [0x%x:0x%x] base_idx:%d bytes_used:%u rc:%d",
+				"VFE", wm_bw_limit_cfg->res_type, wm_bw_limit_cfg->enable_limiter,
+				wm_bw_limit_cfg->counter_limit[0],
+				wm_bw_limit_cfg->counter_limit[1],
+				blob_info->base_info->idx, bytes_used, rc);
+			return rc;
+		}
+
+		total_used_bytes += bytes_used;
+	}
+
+	if (total_used_bytes) {
+		/* Update the HW entries */
+		num_ent = prepare->num_hw_update_entries;
+		prepare->hw_update_entries[num_ent].handle =
+			kmd_buf_info->handle;
+		prepare->hw_update_entries[num_ent].len = total_used_bytes;
+		prepare->hw_update_entries[num_ent].offset =
+			kmd_buf_info->offset;
+		num_ent++;
+		kmd_buf_info->used_bytes += total_used_bytes;
+		kmd_buf_info->offset     += total_used_bytes;
+		prepare->num_hw_update_entries = num_ent;
+	}
+	return rc;
+}
+
+static inline int cam_isp_tfe_validate_bw_limiter_blob(
+	uint32_t blob_size,
+	struct cam_isp_tfe_out_rsrc_bw_limiter_config *bw_limit_config)
+{
+	/* Check for blob version */
+	if (bw_limit_config->version != CAM_TFE_BW_LIMITER_CONFIG_V1) {
+		CAM_ERR(CAM_ISP, "Invalid Blob config version:%d", bw_limit_config->version);
+		return -EINVAL;
+	}
+	/* Check for number of out ports*/
+	if (bw_limit_config->num_ports > CAM_TFE_HW_OUT_RES_MAX) {
+		CAM_ERR(CAM_ISP, "Invalid num_ports:%u", bw_limit_config->num_ports);
+		return -EINVAL;
+	}
+	/* Check for integer overflow */
+	if (bw_limit_config->num_ports != 1) {
+		if (sizeof(struct cam_isp_tfe_wm_bw_limiter_config) > ((UINT_MAX -
+			sizeof(struct cam_isp_tfe_out_rsrc_bw_limiter_config)) /
+			(bw_limit_config->num_ports - 1))) {
+			CAM_ERR(CAM_ISP,
+				"Max size exceeded in bw limit config num_ports:%u size per port:%lu",
+				bw_limit_config->num_ports,
+				sizeof(struct cam_isp_tfe_wm_bw_limiter_config));
+			return -EINVAL;
+		}
+	}
+	if (blob_size < (sizeof(struct cam_isp_tfe_out_rsrc_bw_limiter_config) +
+		(bw_limit_config->num_ports - 1) *
+		sizeof(struct cam_isp_tfe_wm_bw_limiter_config))) {
+		CAM_ERR(CAM_ISP, "Invalid blob size %u expected %lu",
+			blob_size, sizeof(struct cam_isp_tfe_out_rsrc_bw_limiter_config)
+			+ (bw_limit_config->num_ports - 1) *
+			sizeof(struct cam_isp_tfe_wm_bw_limiter_config));
+		return -EINVAL;
+	}
+	return 0;
+}
+
 static int cam_isp_tfe_packet_generic_blob_handler(void *user_data,
 	uint32_t blob_type, uint32_t blob_size, uint8_t *blob_data)
 {
@@ -4092,6 +4223,28 @@ static int cam_isp_tfe_packet_generic_blob_handler(void *user_data,
 			CAM_ERR(CAM_ISP, "Clock Update Failed");
 	}
 		break;
+	case CAM_ISP_TFE_GENERIC_BLOB_TYPE_BW_LIMITER_CFG: {
+		struct cam_isp_tfe_out_rsrc_bw_limiter_config *bw_limit_config;
+
+		if (blob_size <
+			sizeof(struct cam_isp_tfe_out_rsrc_bw_limiter_config)) {
+			CAM_ERR(CAM_ISP, "Invalid blob size %u expected %lu",
+				blob_size,
+				sizeof(struct cam_isp_tfe_out_rsrc_bw_limiter_config));
+			return -EINVAL;
+		}
+
+		bw_limit_config = (struct cam_isp_tfe_out_rsrc_bw_limiter_config *)blob_data;
+		rc = cam_isp_tfe_validate_bw_limiter_blob(blob_size, bw_limit_config);
+		if (rc)
+			return rc;
+
+		rc = cam_isp_tfe_blob_bw_limit_update(blob_type, blob_info,
+			bw_limit_config, prepare, CAM_ISP_HW_TYPE_TFE);
+		if (rc)
+			CAM_ERR(CAM_ISP, "BW limit update failed for TFE rc: %d", rc);
+	}
+		break;
 	default:
 		CAM_WARN(CAM_ISP, "Invalid blob type %d", blob_type);
 		break;

+ 14 - 13
drivers/cam_isp/isp_hw_mgr/include/cam_isp_hw_mgr_intf.h

@@ -16,19 +16,20 @@
 #include "cam_cpas_api.h"
 
 /* MAX IFE instance */
-#define CAM_IFE_HW_NUM_MAX       8
-#define CAM_SFE_HW_NUM_MAX       3
-#define CAM_IFE_RDI_NUM_MAX      4
-#define CAM_SFE_RDI_NUM_MAX      5
-#define CAM_SFE_FE_RDI_NUM_MAX   3
-#define CAM_ISP_BW_CONFIG_V1     1
-#define CAM_ISP_BW_CONFIG_V2     2
-#define CAM_ISP_BW_CONFIG_V3     2
-#define CAM_TFE_HW_NUM_MAX       3
-#define CAM_TFE_RDI_NUM_MAX      3
-#define CAM_IFE_SCRATCH_NUM_MAX  2
-#define CAM_IFE_BUS_COMP_NUM_MAX 18
-#define CAM_SFE_BUS_COMP_NUM_MAX 12
+#define CAM_IFE_HW_NUM_MAX               8
+#define CAM_SFE_HW_NUM_MAX               3
+#define CAM_IFE_RDI_NUM_MAX              4
+#define CAM_SFE_RDI_NUM_MAX              5
+#define CAM_SFE_FE_RDI_NUM_MAX           3
+#define CAM_ISP_BW_CONFIG_V1             1
+#define CAM_ISP_BW_CONFIG_V2             2
+#define CAM_ISP_BW_CONFIG_V3             2
+#define CAM_TFE_HW_NUM_MAX               3
+#define CAM_TFE_RDI_NUM_MAX              3
+#define CAM_IFE_SCRATCH_NUM_MAX          2
+#define CAM_IFE_BUS_COMP_NUM_MAX         18
+#define CAM_SFE_BUS_COMP_NUM_MAX         12
+#define CAM_TFE_BW_LIMITER_CONFIG_V1     1
 
 /* maximum context numbers for TFE */
 #define CAM_TFE_CTX_MAX      4

+ 4 - 0
drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe530.h

@@ -1,6 +1,7 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
  * Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 
@@ -855,6 +856,9 @@ static struct cam_tfe_bus_hw_info  tfe530_bus_hw_info = {
 	.support_consumed_addr = true,
 	.pdaf_rdi2_mux_en = true,
 	.rdi_width = 64,
+	.max_bw_counter_limit  = 0xFF,
+	.counter_limit_shift   = 1,
+	.counter_limit_mask    = 0xF,
 };
 
 struct cam_tfe_hw_info cam_tfe530 = {

+ 4 - 0
drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe640.h

@@ -1,6 +1,7 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
  * Copyright (c) 2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 
@@ -1170,6 +1171,9 @@ static struct cam_tfe_bus_hw_info  tfe640_bus_hw_info = {
 	.support_consumed_addr = true,
 	.pdaf_rdi2_mux_en = false,
 	.rdi_width = 128,
+	.max_bw_counter_limit  = 0xFF,
+	.counter_limit_shift   = 1,
+	.counter_limit_mask    = 0xF,
 };
 
 struct cam_tfe_hw_info cam_tfe640 = {

+ 114 - 2
drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe_bus.c

@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
  * Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include <linux/ratelimit.h>
@@ -75,6 +75,9 @@ struct cam_tfe_bus_common_data {
 	cam_hw_mgr_event_cb_func                    event_cb;
 	bool                        rup_irq_enable[CAM_TFE_BUS_RUP_GRP_MAX];
 	bool                                        pdaf_rdi2_mux_en;
+	uint32_t                                    max_bw_counter_limit;
+	uint32_t                                    counter_limit_shift;
+	uint32_t                                    counter_limit_mask;
 };
 
 struct cam_tfe_bus_wm_resource_data {
@@ -104,6 +107,7 @@ struct cam_tfe_bus_wm_resource_data {
 	uint32_t             acquired_width;
 	uint32_t             acquired_height;
 	uint32_t             acquired_stride;
+	bool                 limiter_blob_status;
 };
 
 struct cam_tfe_bus_comp_grp_data {
@@ -848,6 +852,7 @@ static int cam_tfe_bus_release_wm(void   *bus_priv,
 	rsrc_data->framedrop_pattern = 0;
 	rsrc_data->en_cfg = 0;
 	rsrc_data->is_dual = 0;
+	rsrc_data->limiter_blob_status = false;
 
 	wm_res->tasklet_info = NULL;
 	wm_res->res_state = CAM_ISP_RESOURCE_STATE_AVAILABLE;
@@ -865,7 +870,10 @@ static int cam_tfe_bus_start_wm(struct cam_isp_resource_node *wm_res)
 	struct cam_tfe_bus_common_data        *common_data =
 		rsrc_data->common_data;
 
-	cam_io_w(0xf, common_data->mem_base + rsrc_data->hw_regs->bw_limit);
+	/* Skip to overwrite if wm bandwidth limiter blob already sent */
+	if (!rsrc_data->limiter_blob_status)
+		cam_io_w(rsrc_data->common_data->counter_limit_mask,
+			common_data->mem_base + rsrc_data->hw_regs->bw_limit);
 
 	cam_io_w((rsrc_data->height << 16) | rsrc_data->width,
 		common_data->mem_base + rsrc_data->hw_regs->image_cfg_0);
@@ -2309,6 +2317,104 @@ end:
 	return 0;
 }
 
+static int cam_tfe_bus_update_bw_limiter(
+	void *priv, void *cmd_args, uint32_t arg_size)
+{
+	struct cam_tfe_bus_priv                  *bus_priv;
+	struct cam_isp_hw_get_cmd_update         *wm_config_update;
+	struct cam_tfe_bus_tfe_out_data          *tfe_out_data = NULL;
+	struct cam_cdm_utils_ops                 *cdm_util_ops;
+	struct cam_tfe_bus_wm_resource_data      *wm_data = NULL;
+	struct cam_isp_tfe_wm_bw_limiter_config  *wm_bw_limit_cfg = NULL;
+	uint32_t                                  counter_limit = 0, reg_val = 0;
+	uint32_t                                 *reg_val_pair, num_regval_pairs = 0;
+	uint32_t                                  i, j, size = 0;
+
+	bus_priv         = (struct cam_tfe_bus_priv  *) priv;
+	wm_config_update = (struct cam_isp_hw_get_cmd_update *) cmd_args;
+	wm_bw_limit_cfg  = (struct cam_isp_tfe_wm_bw_limiter_config  *) wm_config_update->data;
+
+	tfe_out_data = (struct cam_tfe_bus_tfe_out_data *) wm_config_update->res->res_priv;
+	if (!tfe_out_data || !tfe_out_data->cdm_util_ops) {
+		CAM_ERR(CAM_ISP, "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 for WM idx %d",
+				j, MAX_REG_VAL_PAIR_SIZE, i);
+			return -ENOMEM;
+		}
+
+		/* Num WMs needs to match max planes */
+		if (i >= CAM_PACKET_MAX_PLANES) {
+			CAM_WARN(CAM_ISP, "Num of WMs: %d exceeded max planes", i);
+			goto add_reg_pair;
+		}
+
+		wm_data = (struct cam_tfe_bus_wm_resource_data *) tfe_out_data->wm_res[i]->res_priv;
+		if (!wm_data->hw_regs->bw_limit) {
+			CAM_ERR(CAM_ISP,
+				"WM: %d %s has no support for bw limiter",
+				wm_data->index, tfe_out_data->wm_res[i]->res_name);
+			return -EINVAL;
+		}
+
+		counter_limit = wm_bw_limit_cfg->counter_limit[i];
+
+		/* Validate max counter limit */
+		if (counter_limit > wm_data->common_data->max_bw_counter_limit) {
+			CAM_WARN(CAM_ISP, "Invalid counter limit: 0x%x capping to max: 0x%x",
+				wm_bw_limit_cfg->counter_limit[i],
+				wm_data->common_data->max_bw_counter_limit);
+			counter_limit = wm_data->common_data->max_bw_counter_limit;
+		}
+
+		if (wm_bw_limit_cfg->enable_limiter && counter_limit) {
+			reg_val = 1;
+			reg_val |= (counter_limit << wm_data->common_data->counter_limit_shift);
+		} else {
+			reg_val = 0;
+		}
+
+		wm_data->limiter_blob_status = true;
+
+		CAM_TFE_ADD_REG_VAL_PAIR(reg_val_pair, j, wm_data->hw_regs->bw_limit, reg_val);
+		CAM_DBG(CAM_ISP, "WM: %d for %s bw_limter: 0x%x",
+			wm_data->index, tfe_out_data->wm_res[i]->res_name, reg_val_pair[j-1]);
+	}
+
+add_reg_pair:
+
+	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) > wm_config_update->cmd.size) {
+			CAM_ERR(CAM_ISP, "Failed! Buf size:%d insufficient, expected size:%d",
+				wm_config_update->cmd.size, size);
+			return -ENOMEM;
+		}
+
+		cdm_util_ops->cdm_write_regrandom(
+			wm_config_update->cmd.cmd_buf_addr, num_regval_pairs, reg_val_pair);
+
+		/* cdm util returns dwords, need to convert to bytes */
+		wm_config_update->cmd.used_bytes = size * 4;
+	} else {
+		CAM_DBG(CAM_ISP, "No reg val pairs. num_wms: %u", tfe_out_data->num_wm);
+		wm_config_update->cmd.used_bytes = 0;
+	}
+
+	return 0;
+}
+
 static int cam_tfe_bus_dump_bus_info(
 	struct cam_tfe_bus_priv    *bus_priv,
 	void *cmd_args, uint32_t arg_size)
@@ -2484,6 +2590,9 @@ static int cam_tfe_bus_process_cmd(void *priv,
 		pdaf_rdi2_mux_en = (bool *)cmd_args;
 		*pdaf_rdi2_mux_en = bus_priv->common_data.pdaf_rdi2_mux_en;
 		break;
+	case CAM_ISP_HW_CMD_WM_BW_LIMIT_CONFIG:
+		rc = cam_tfe_bus_update_bw_limiter(priv, cmd_args, arg_size);
+		break;
 	default:
 		CAM_ERR_RATE_LIMIT(CAM_ISP, "Invalid camif process command:%d",
 			cmd_type);
@@ -2550,6 +2659,9 @@ int cam_tfe_bus_init(
 		hw_info->support_consumed_addr;
 	bus_priv->common_data.pdaf_rdi2_mux_en = hw_info->pdaf_rdi2_mux_en;
 	bus_priv->common_data.rdi_width = hw_info->rdi_width;
+	bus_priv->common_data.max_bw_counter_limit = hw_info->max_bw_counter_limit;
+	bus_priv->common_data.counter_limit_shift = hw_info->counter_limit_shift;
+	bus_priv->common_data.counter_limit_mask = hw_info->counter_limit_mask;
 
 	for (i = 0; i < CAM_TFE_BUS_IRQ_REGISTERS_MAX; i++)
 		bus_priv->bus_irq_error_mask[i] =

+ 7 - 0
drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe_bus.h

@@ -1,6 +1,7 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
  * Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 
@@ -195,6 +196,9 @@ struct cam_tfe_bus_tfe_out_hw_info {
  * @rdi_width:             RDI WM width
  * @support_consumed_addr: Indicate if bus support consumed address
  * @pdaf_rdi2_mux_en:      Indicate is PDAF is muxed with RDI2
+ * @max_bw_counter_limit:  Max BW counter limit
+ * @counter_limit_shift:   Mask shift for BW counter limit
+ * @counter_limit_mask:    Default Mask of BW limit counter
  */
 struct cam_tfe_bus_hw_info {
 	struct cam_tfe_bus_reg_offset_common common_reg;
@@ -214,6 +218,9 @@ struct cam_tfe_bus_hw_info {
 	uint32_t rdi_width;
 	bool support_consumed_addr;
 	bool pdaf_rdi2_mux_en;
+	uint32_t max_bw_counter_limit;
+	uint32_t counter_limit_shift;
+	uint32_t counter_limit_mask;
 };
 
 /*

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

@@ -2919,6 +2919,7 @@ int cam_tfe_process_cmd(void *hw_priv, uint32_t cmd_type,
 	case CAM_ISP_HW_CMD_GET_RES_FOR_MID:
 	case CAM_ISP_HW_CMD_DUMP_BUS_INFO:
 	case CAM_ISP_HW_CMD_IS_PDAF_RDI2_MUX_EN:
+	case CAM_ISP_HW_CMD_WM_BW_LIMIT_CONFIG:
 		rc = core_info->tfe_bus->hw_ops.process_cmd(
 			core_info->tfe_bus->bus_priv, cmd_type, cmd_args,
 			arg_size);

+ 32 - 0
include/uapi/camera/media/cam_tfe.h

@@ -1,6 +1,7 @@
 /* SPDX-License-Identifier: GPL-2.0-only WITH Linux-syscall-note */
 /*
  * Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2023, Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #ifndef __UAPI_CAM_TFE_H__
@@ -71,6 +72,7 @@
 #define CAM_ISP_TFE_GENERIC_BLOB_TYPE_CLOCK_CONFIG        1
 #define CAM_ISP_TFE_GENERIC_BLOB_TYPE_BW_CONFIG_V2        2
 #define CAM_ISP_TFE_GENERIC_BLOB_TYPE_CSID_CLOCK_CONFIG   3
+#define CAM_ISP_TFE_GENERIC_BLOB_TYPE_BW_LIMITER_CFG      16
 
 /* DSP mode */
 #define CAM_ISP_TFE_DSP_MODE_NONE                   0
@@ -473,6 +475,36 @@ struct cam_isp_tfe_acquire_hw_info {
 	__u64                data;
 };
 
+/**
+ * struct cam_isp_tfe_wm_bw_limiter_config - ISP TFE write master
+ *                                       BW limter config
+ *
+ *
+ * @res_type          : output resource type defined in file cam_isp_tfe.h
+ * @enable_limiter    : 0 for disable else enabled
+ * @counter_limit     : Max counter value
+ */
+struct cam_isp_tfe_wm_bw_limiter_config {
+	__u32         res_type;
+	__u32         enable_limiter;
+	__u32         counter_limit[CAM_PACKET_MAX_PLANES];
+};
+
+/**
+ * struct cam_isp_tfe_out_rsrc_bw_limiter_config - ISP TFE out rsrc BW limiter config
+ *
+ *    Configure BW limiter for ISP TFE WMs
+ *
+ * @version          : Version field
+ * @num_ports        : Number of ports
+ * @bw_limit_config  : WM BW limiter config
+ */
+struct cam_isp_tfe_out_rsrc_bw_limiter_config {
+	__u32                                       version;
+	__u32                                       num_ports;
+	struct cam_isp_tfe_wm_bw_limiter_config     bw_limiter_config[1];
+};
+
 #define CAM_TFE_ACQUIRE_COMMON_VER0         0x1000
 
 #define CAM_TFE_ACQUIRE_COMMON_SIZE_VER0    0x0