Browse Source

msm: camera: cpas: llcc frame staling implementation

Adding support for LLCC sys cache notify stalling feature.
To  influence the cache replacement policy in real time in order to,
improve cache performance and reduce DDR bandwidth.

CRs-Fixed: 3376264
Change-Id: Id82f60fb856b3548bad77670c7c45c81ea1e904f
Signed-off-by: Soumen Ghosh <[email protected]>
Soumen Ghosh 2 years ago
parent
commit
6fbf41d2a1

+ 2 - 0
config/pineapple.mk

@@ -7,6 +7,7 @@ CONFIG_SPECTRA_JPEG := y
 CONFIG_SPECTRA_CUSTOM := y
 CONFIG_SPECTRA_SENSOR := y
 CONFIG_USE_RPMH_DRV_API := y
+CONFIG_SPECTRA_LLCC_STALING := y
 
 # Flags to pass into C preprocessor
 ccflags-y += -DCONFIG_SPECTRA_ISP=1
@@ -15,6 +16,7 @@ ccflags-y += -DCONFIG_SPECTRA_JPEG=1
 ccflags-y += -DCONFIG_SPECTRA_CUSTOM=1
 ccflags-y += -DCONFIG_SPECTRA_SENSOR=1
 ccflags-y += -DCONFIG_USE_RPMH_DRV_API=1
+ccflags-y += -DCONFIG_SPECTRA_LLCC_STALING=1
 
 # External Dependencies
 KBUILD_CPPFLAGS += -DCONFIG_MSM_MMRM=1

+ 176 - 1
drivers/cam_cpas/cam_cpas_hw.c

@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
  * Copyright (c) 2017-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/device.h>
@@ -3467,6 +3467,87 @@ static int cam_cpas_deactivate_cache(
 	return rc;
 }
 
+#if IS_ENABLED(CONFIG_SPECTRA_LLCC_STALING)
+static int cam_cpas_configure_staling_cache(
+	struct cam_hw_info *cpas_hw,
+	struct cam_sys_cache_info *cache_info,
+	struct cam_sys_cache_local_info *sys_cache_info)
+{
+	int rc = 0;
+	struct llcc_staling_mode_params staling_params;
+
+	mutex_lock(&cpas_hw->hw_mutex);
+	switch (sys_cache_info->mode) {
+	case CAM_LLCC_STALING_MODE_CAPACITY: {
+		staling_params.staling_mode = LLCC_STALING_MODE_CAPACITY;
+		break;
+	}
+	case LLCC_STALING_MODE_NOTIFY: {
+		staling_params.staling_mode = LLCC_STALING_MODE_NOTIFY;
+		break;
+	}
+	default:
+		CAM_ERR(CAM_CPAS, "CPAS LLCC sys cache mode is not valid =%d"
+				, sys_cache_info->mode);
+		break;
+	}
+
+	switch (sys_cache_info->op_type) {
+	case CAM_LLCC_NOTIFY_STALING_EVICT: {
+		staling_params.notify_params.op = LLCC_NOTIFY_STALING_WRITEBACK;
+		break;
+	}
+	default:
+		CAM_ERR(CAM_CPAS, "CPAS LLCC sys cache op_type is not valid =%d"
+				, sys_cache_info->op_type);
+		break;
+	}
+	staling_params.notify_params.staling_distance
+		= cache_info->staling_distance;
+	rc = llcc_configure_staling_mode(cache_info->slic_desc,
+			&staling_params);
+	if (!rc) {
+		cache_info->staling_distance = sys_cache_info->staling_distance;
+		cache_info->mode = sys_cache_info->mode;
+		cache_info->op_type = sys_cache_info->op_type;
+	} else if (rc == -EOPNOTSUPP) {
+		CAM_ERR(CAM_CPAS, "llcc staling feature is not supported cache:%s",
+			cache_info->name);
+	} else if (rc) {
+		CAM_ERR(CAM_CPAS, "Failed to enable llcc notif cache:%s",
+			cache_info->name);
+	}
+
+	mutex_unlock(&cpas_hw->hw_mutex);
+	CAM_DBG(CAM_CPAS,
+		"llcc notif cache name:%s staling_distance %d cache mode :%d cache op_type :%s",
+		cache_info->name, cache_info->staling_distance,
+		cache_info->mode, cache_info->op_type);
+	return rc;
+}
+
+static int cam_cpas_notif_stalling_inc_cache(
+	struct cam_hw_info *cpas_hw,
+	struct cam_sys_cache_info *cache_info)
+{
+	int rc = 0;
+
+	mutex_lock(&cpas_hw->hw_mutex);
+	rc = llcc_notif_staling_inc_counter(cache_info->slic_desc);
+	if (rc == -EOPNOTSUPP)
+		CAM_ERR(CAM_CPAS, "llcc notif stalling inc not supported: %s",
+			cache_info->name);
+	else if (rc)
+		CAM_ERR(CAM_CPAS, "Failed to llcc staling frame trigger:%s",
+			cache_info->name);
+
+	mutex_unlock(&cpas_hw->hw_mutex);
+	CAM_DBG(CAM_CPAS, "llcc staling frame triggered cache:%s",
+		cache_info->name);
+	return rc;
+}
+#endif
+
 static inline int cam_cpas_validate_cache_type(
 	uint32_t num_caches, enum cam_sys_cache_config_types type)
 {
@@ -3547,6 +3628,75 @@ end:
 	return rc;
 }
 
+#if IS_ENABLED(CONFIG_SPECTRA_LLCC_STALING)
+static int cam_cpas_configure_staling_cache_slice(
+	struct cam_hw_info *cpas_hw,
+	struct cam_sys_cache_local_info sys_cache_info)
+{
+	struct cam_cpas_private_soc *soc_private =
+		(struct cam_cpas_private_soc *)cpas_hw->soc_info.soc_private;
+	uint32_t num_caches = soc_private->num_caches;
+	int rc = 0, i;
+
+	CAM_DBG(CAM_CPAS, "De-activate type: %d", sys_cache_info.type);
+	if (cam_cpas_validate_cache_type(num_caches, sys_cache_info.type))
+		goto end;
+
+	for (i = 0; i < num_caches; i++) {
+		if (sys_cache_info.type == soc_private->llcc_info[i].type) {
+			rc = cam_cpas_configure_staling_cache(cpas_hw,
+				&soc_private->llcc_info[i], &sys_cache_info);
+			if (rc) {
+				CAM_ERR(CAM_CPAS, "llc sys cache type %d config failed, rc: %d",
+					soc_private->llcc_info[i].type, rc);
+			}
+			break;
+		}
+	}
+
+end:
+	return rc;
+}
+
+static int cam_cpas_notif_stalling_inc_cache_slice(
+	struct cam_hw_info *cpas_hw,
+	enum cam_sys_cache_config_types type)
+{
+	struct cam_cpas_private_soc *soc_private =
+		(struct cam_cpas_private_soc *)cpas_hw->soc_info.soc_private;
+	uint32_t num_caches = soc_private->num_caches;
+	int rc = 0, i;
+
+	CAM_DBG(CAM_CPAS, "De-activate type: %d", type);
+	if (cam_cpas_validate_cache_type(num_caches, type))
+		goto end;
+
+	for (i = 0; i < num_caches; i++) {
+		if (type == soc_private->llcc_info[i].type)
+			rc = cam_cpas_notif_stalling_inc_cache(cpas_hw,
+				&soc_private->llcc_info[i]);
+	}
+
+end:
+	return rc;
+}
+
+#else
+static int cam_cpas_configure_staling_cache_slice(
+	struct cam_hw_info *cpas_hw,
+	struct cam_sys_cache_local_info sys_cache_info)
+{
+	return -EOPNOTSUPP;
+}
+
+static int cam_cpas_notif_stalling_inc_cache_slice(
+	struct cam_hw_info *cpas_hw,
+	enum cam_sys_cache_config_types type)
+{
+	return -EOPNOTSUPP;
+}
+#endif
+
 static int cam_cpas_hw_csid_input_core_info_update(struct cam_hw_info *cpas_hw,
 	int csid_idx, int sfe_idx, bool set_port)
 {
@@ -3858,6 +4008,31 @@ static int cam_cpas_hw_process_cmd(void *hw_priv,
 		rc = cam_cpas_deactivate_cache_slice(hw_priv, type);
 	}
 		break;
+	case CAM_CPAS_HW_CMD_CONFIGURE_STALING_LLC: {
+		struct cam_sys_cache_local_info sys_cache_info;
+
+		if (sizeof(struct cam_sys_cache_local_info) != arg_size) {
+			CAM_ERR(CAM_CPAS, "cmd_type %d, size mismatch %d",
+				cmd_type, arg_size);
+			break;
+		}
+		sys_cache_info =
+			*((struct cam_sys_cache_local_info *) cmd_args);
+		rc = cam_cpas_configure_staling_cache_slice(hw_priv, sys_cache_info);
+	}
+		break;
+	case CAM_CPAS_HW_CMD_NOTIF_STALL_INC_LLC: {
+		enum cam_sys_cache_config_types type;
+
+		if (sizeof(enum cam_sys_cache_config_types) != arg_size) {
+			CAM_ERR(CAM_CPAS, "cmd_type %d, size mismatch %d",
+				cmd_type, arg_size);
+			break;
+		}
+		type = *((enum cam_sys_cache_config_types *) cmd_args);
+		rc = cam_cpas_notif_stalling_inc_cache_slice(hw_priv, type);
+	}
+		break;
 	case CAM_CPAS_HW_CMD_DUMP_BUFF_FILL_INFO: {
 		uint32_t *client_handle;
 

+ 3 - 1
drivers/cam_cpas/cam_cpas_hw_intf.h

@@ -1,7 +1,7 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
  * Copyright (c) 2017-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.
  */
 
 #ifndef _CAM_CPAS_HW_INTF_H_
@@ -47,6 +47,8 @@ enum cam_cpas_hw_cmd_process {
 	CAM_CPAS_HW_CMD_GET_SCID,
 	CAM_CPAS_HW_CMD_ACTIVATE_LLC,
 	CAM_CPAS_HW_CMD_DEACTIVATE_LLC,
+	CAM_CPAS_HW_CMD_CONFIGURE_STALING_LLC,
+	CAM_CPAS_HW_CMD_NOTIF_STALL_INC_LLC,
 	CAM_CPAS_HW_CMD_DUMP_BUFF_FILL_INFO,
 	CAM_CPAS_HW_CMD_CSID_INPUT_CORE_INFO_UPDATE,
 	CAM_CPAS_HW_CMD_CSID_PROCESS_RESUME,

+ 84 - 0
drivers/cam_cpas/cam_cpas_intf.c

@@ -21,6 +21,7 @@
 #include "cam_cpas_hw_intf.h"
 #include "cam_cpas_soc.h"
 #include "camera_main.h"
+#include <linux/soc/qcom/llcc-qcom.h>
 
 #define CAM_CPAS_DEV_NAME    "cam-cpas"
 #define CAM_CPAS_INTF_INITIALIZED() (g_cpas_intf && g_cpas_intf->probe_done)
@@ -859,6 +860,89 @@ int cam_cpas_deactivate_llcc(
 }
 EXPORT_SYMBOL(cam_cpas_deactivate_llcc);
 
+int cam_cpas_configure_staling_llcc(
+	enum cam_sys_cache_config_types type,
+	enum cam_sys_cache_llcc_staling_mode mode_param,
+	enum cam_sys_cache_llcc_staling_op_type operation_type,
+	uint32_t staling_distance)
+{
+	int rc;
+	struct cam_hw_info *cpas_hw = NULL;
+	struct cam_cpas_private_soc *soc_private = NULL;
+	uint32_t num_caches = 0;
+	struct cam_sys_cache_local_info sys_cache_info;
+
+	if (!CAM_CPAS_INTF_INITIALIZED()) {
+		CAM_ERR(CAM_CPAS, "cpas intf not initialized");
+		return -ENODEV;
+	}
+	cpas_hw = (struct cam_hw_info *) g_cpas_intf->hw_intf->hw_priv;
+	soc_private =
+		(struct cam_cpas_private_soc *)cpas_hw->soc_info.soc_private;
+	num_caches = soc_private->num_caches;
+	if (!cam_cpas_is_notif_staling_supported())
+		return -EOPNOTSUPP;
+
+	sys_cache_info.mode = mode_param;
+	sys_cache_info.op_type = operation_type;
+	sys_cache_info.staling_distance
+		= staling_distance;
+	sys_cache_info.type = type;
+
+	if (g_cpas_intf->hw_intf->hw_ops.process_cmd) {
+		rc = g_cpas_intf->hw_intf->hw_ops.process_cmd(
+			g_cpas_intf->hw_intf->hw_priv,
+			CAM_CPAS_HW_CMD_CONFIGURE_STALING_LLC, &sys_cache_info,
+			sizeof(struct cam_sys_cache_local_info));
+		if (rc)
+			CAM_ERR(CAM_CPAS, "Failed in process_cmd, rc=%d", rc);
+	} else {
+		CAM_ERR(CAM_CPAS, "Invalid process_cmd ops");
+		rc = -EINVAL;
+	}
+
+	return rc;
+}
+EXPORT_SYMBOL(cam_cpas_configure_staling_llcc);
+
+int cam_cpas_notif_increment_staling_counter(
+	enum cam_sys_cache_config_types type)
+{
+	int rc;
+
+	if (!CAM_CPAS_INTF_INITIALIZED()) {
+		CAM_ERR(CAM_CPAS, "cpas intf not initialized");
+		return -ENODEV;
+	}
+	if (!cam_cpas_is_notif_staling_supported())
+		return -EOPNOTSUPP;
+
+	if (g_cpas_intf->hw_intf->hw_ops.process_cmd) {
+		rc = g_cpas_intf->hw_intf->hw_ops.process_cmd(
+			g_cpas_intf->hw_intf->hw_priv,
+			CAM_CPAS_HW_CMD_NOTIF_STALL_INC_LLC, &type,
+			sizeof(type));
+		if (rc)
+			CAM_ERR(CAM_CPAS, "Failed in process_cmd, rc=%d", rc);
+	} else {
+		CAM_ERR(CAM_CPAS, "Invalid process_cmd ops");
+		rc = -EINVAL;
+	}
+
+	return rc;
+}
+EXPORT_SYMBOL(cam_cpas_notif_increment_staling_counter);
+
+bool cam_cpas_is_notif_staling_supported(void)
+{
+	#if IS_ENABLED(CONFIG_SPECTRA_LLCC_STALING)
+		return true;
+	#else
+		return false;
+	#endif
+}
+EXPORT_SYMBOL(cam_cpas_is_notif_staling_supported);
+
 bool cam_cpas_query_domain_id_security_support(void)
 {
 	struct cam_hw_info *cpas_hw = NULL;

+ 4 - 1
drivers/cam_cpas/cam_cpas_soc.c

@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
  * Copyright (c) 2017-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/device.h>
@@ -1000,6 +1000,9 @@ static int cam_cpas_parse_sys_cache_uids(
 		soc_private->llcc_info[i].scid = scid;
 		soc_private->llcc_info[i].size =
 			llcc_get_slice_size(soc_private->llcc_info[i].slic_desc);
+		soc_private->llcc_info[i].staling_distance = 0;
+		soc_private->llcc_info[i].mode = CAM_LLCC_STALING_MODE_CAPACITY;
+		soc_private->llcc_info[i].op_type = CAM_LLCC_NOTIFY_STALING_EVICT;
 		soc_private->num_caches++;
 
 		CAM_DBG(CAM_CPAS,

+ 23 - 1
drivers/cam_cpas/cam_cpas_soc.h

@@ -1,7 +1,7 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
  * Copyright (c) 2017-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.
  */
 
 #ifndef _CAM_CPAS_SOC_H_
@@ -90,6 +90,21 @@ struct cam_cpas_feature_info {
 	uint32_t hw_map;
 };
 
+/**
+ * struct cam_sys_cache_local_info : camera cache info saving locally
+ *
+ * @type:      cache type small/large etc.
+ * @staling_distance:       staling_distance
+ * @mode:      camera llc's stalling mode
+ * @op_type:      cache operation type EVICT, FORGET
+ */
+struct cam_sys_cache_local_info {
+	enum cam_sys_cache_config_types  type;
+	uint32_t staling_distance;
+	enum cam_sys_cache_llcc_staling_mode mode;
+	enum cam_sys_cache_llcc_staling_op_type op_type;
+};
+
 /**
  * struct cam_sys_cache_info : Last level camera cache info
  *
@@ -99,6 +114,9 @@ struct cam_cpas_feature_info {
  * @size:      Cache size
  * @scid:      Slice ID
  * @slic_desc: Slice descriptor
+ * @staling_distance:       staling_distance
+ * @mode:      camera llc's stalling mode
+ * @op_type:      cache operation type EVICT, FORGET
  */
 struct cam_sys_cache_info {
 	uint32_t                         ref_cnt;
@@ -108,6 +126,10 @@ struct cam_sys_cache_info {
 	int32_t                          scid;
 	const char                      *name;
 	struct llcc_slice_desc          *slic_desc;
+	uint32_t staling_distance;
+	enum cam_sys_cache_llcc_staling_mode mode;
+	enum cam_sys_cache_llcc_staling_op_type op_type;
+
 };
 
 

+ 64 - 1
drivers/cam_cpas/include/cam_cpas_api.h

@@ -1,7 +1,7 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
  * Copyright (c) 2017-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.
  */
 
 #ifndef _CAM_CPAS_API_H_
@@ -31,6 +31,7 @@
 #define CAM_CPAS_QOS_DEFAULT_SETTINGS_MASK 0x1
 #define CAM_CPAS_QOS_CUSTOM_SETTINGS_MASK  0x2
 
+
 /**
  * enum cam_cpas_vote_type - Enum for cpas vote type
  */
@@ -275,6 +276,24 @@ enum cam_sys_cache_config_types {
 	CAM_LLCC_MAX     = 6,
 };
 
+/**
+ * enum cam_sys_cache_llcc_staling_mode - Enum for camera llc's stalling mode
+ */
+enum cam_sys_cache_llcc_staling_mode {
+	CAM_LLCC_STALING_MODE_CAPACITY,
+	CAM_LLCC_STALING_MODE_NOTIFY,
+	CAM_LLCC_STALING_MODE_MAX,
+};
+
+/**
+ * enum cam_sys_cache_llcc_staling_mode - Enum for camera llc's stalling mode
+ */
+enum cam_sys_cache_llcc_staling_op_type {
+	CAM_LLCC_NOTIFY_STALING_EVICT,
+	CAM_LLCC_NOTIFY_STALING_FORGET,
+	CAM_LLCC_NOTIFY_STALING_OPS_MAX
+};
+
 /**
  * struct cam_camnoc_irq_slave_err_data : Data for Slave error.
  *
@@ -876,6 +895,41 @@ int cam_cpas_activate_llcc(enum cam_sys_cache_config_types type);
  */
 int cam_cpas_deactivate_llcc(enum cam_sys_cache_config_types type);
 
+/**
+ * cam_cpas_configure_staling_llcc()
+ *
+ * @brief:  Configure cache staling mode by setting the
+ *          staling_mode and corresponding params
+ *
+ * @type: Cache type
+ * @mode_param: llcc stalling mode params
+ * @operation_type: cache operation type
+ * @stalling_distance: llcc sys cache stalling distance
+ *
+ * @return 0 for success.
+ *
+ */
+int cam_cpas_configure_staling_llcc(
+	enum cam_sys_cache_config_types type,
+	enum cam_sys_cache_llcc_staling_mode mode_param,
+	enum cam_sys_cache_llcc_staling_op_type operation_type,
+	uint32_t staling_distance);
+
+/**
+ * cam_cpas_notif_increment_staling_counter()
+ *
+ * @brief: This will increment the stalling counter
+ *         depends on what operation it does.
+ *         The operation mode what we have setup in other function.
+ *
+ * @type: Cache type
+ *
+ * @return 0 for success.
+ *
+ */
+int cam_cpas_notif_increment_staling_counter(
+	enum cam_sys_cache_config_types type);
+
 /**
  * cam_cpas_dump_camnoc_buff_fill_info()
  *
@@ -945,4 +999,13 @@ bool cam_cpas_query_domain_id_security_support(void);
  */
 int cam_cpas_enable_clks_for_domain_id(bool enable);
 
+/**
+ * cam_cpas_is_notif_staling_supported()
+ *
+ * @brief: API to check stalling feature is supported or not
+ *
+ * @return rue if supported
+ */
+bool cam_cpas_is_notif_staling_supported(void);
+
 #endif /* _CAM_CPAS_API_H_ */

+ 53 - 6
drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c

@@ -1131,7 +1131,7 @@ static void cam_ife_hw_mgr_deinit_hw(
 {
 	struct cam_isp_hw_mgr_res *hw_mgr_res;
 	struct cam_ife_hw_mgr          *hw_mgr;
-	int i = 0, j;
+	int i = 0, j, rc;
 
 	if (!ctx->flags.init_done) {
 		CAM_WARN(CAM_ISP, "ctx is not in init state, ctx_idx: %u", ctx->ctx_index);
@@ -1186,8 +1186,16 @@ static void cam_ife_hw_mgr_deinit_hw(
 	 * for a particular exposure. Check if any cache needs to be de-activated
 	 */
 	for (i = CAM_LLCC_SMALL_1; i < CAM_LLCC_MAX; i++) {
-		if (ctx->flags.sys_cache_usage[i])
+		if (ctx->flags.sys_cache_usage[i]) {
+			if (cam_cpas_is_notif_staling_supported() &&
+				hw_mgr->sys_cache_info[i].llcc_staling_support) {
+				rc = cam_cpas_notif_increment_staling_counter(i);
+				if (rc)
+					CAM_ERR(CAM_ISP,
+						"llcc cache notif increment staling failed %d", i);
+			}
 			cam_cpas_deactivate_llcc(i);
+		}
 		ctx->flags.sys_cache_usage[i] = false;
 	}
 
@@ -8302,6 +8310,7 @@ static uint32_t cam_ife_hw_mgr_get_sfe_sys_cache_id(uint32_t exp_type,
 	unsigned long          supported_sc_idx;
 	struct                 cam_ife_hw_mgr *hw_mgr;
 	bool                   use_large;
+	int                    rc;
 
 	hw_mgr = ctx->hw_mgr;
 	supported_sc_idx = hw_mgr->sfe_cache_info[hw_idx].supported_scid_idx;
@@ -8360,6 +8369,13 @@ static uint32_t cam_ife_hw_mgr_get_sfe_sys_cache_id(uint32_t exp_type,
 			cam_cpas_activate_llcc(scid_idx);
 
 		hw_mgr->sfe_cache_info[hw_idx].activated[exp_type] = true;
+		if (cam_cpas_is_notif_staling_supported()
+			&& hw_mgr->sys_cache_info[scid_idx].llcc_staling_support) {
+			rc = cam_cpas_notif_increment_staling_counter(scid_idx);
+			if (rc)
+				CAM_ERR(CAM_ISP,
+					"llcc cache notif increment staling failed %d", scid_idx);
+		}
 
 		CAM_DBG(CAM_ISP, "SFE %u Exp type %u SCID index %d use_large %d ctx_idx: %u",
 			hw_idx, exp_type, scid_idx, use_large, ctx->ctx_index);
@@ -15236,7 +15252,7 @@ static void cam_ife_hw_mgr_attach_sfe_sys_cache_id(
 	}
 }
 
-static void cam_ife_mgr_populate_sys_cache_id(void)
+static int cam_ife_mgr_populate_sys_cache_id(void)
 {
 	int                             i, scid, j;
 	uint32_t                        hw_id = 0;
@@ -15244,6 +15260,7 @@ static void cam_ife_mgr_populate_sys_cache_id(void)
 	uint32_t                        num_large_scid = 0;
 	uint32_t                        num_sfe = 0;
 	bool                            shared;
+	int rc = 0;
 
 	/* Populate sys cache info */
 	g_ife_hw_mgr.num_caches_found = 0;
@@ -15257,7 +15274,7 @@ static void cam_ife_mgr_populate_sys_cache_id(void)
 	}
 
 	if (!num_sfe)
-		return;
+		return rc;
 
 	for (i = CAM_LLCC_SMALL_1; i < CAM_LLCC_MAX; i++) {
 		scid = cam_cpas_get_scid(i);
@@ -15300,12 +15317,39 @@ static void cam_ife_mgr_populate_sys_cache_id(void)
 			continue;
 		cam_ife_hw_mgr_attach_sfe_sys_cache_id(shared,
 			g_ife_hw_mgr.sys_cache_info[i].type, &hw_id, num_sfe);
+		g_ife_hw_mgr.sys_cache_info[i].llcc_staling_support = false;
+		rc = cam_cpas_configure_staling_llcc(i,
+				CAM_LLCC_STALING_MODE_NOTIFY,
+				CAM_LLCC_NOTIFY_STALING_EVICT,
+				1);
+		if ((num_large_scid == 1) && (num_large_scid < num_sfe) &&
+			(rc == -EOPNOTSUPP)) {
+			CAM_ERR(CAM_ISP,
+			"Fatal error llcc staling feature is not supported cache: %d", i);
+			rc = -EFAULT;
+		} else if (!rc && num_large_scid > 1) {
+			CAM_ERR(CAM_ISP,
+			"Fatal error llcc staling feature is supported more large cache %d", i);
+			rc = -EFAULT;
+		} else if (rc == -EOPNOTSUPP) {
+			CAM_ERR(CAM_ISP,
+			"llcc staling feature is not supported cache: %d", i);
+		} else if (rc) {
+			CAM_ERR(CAM_ISP,
+			"llcc staling feature enabling failing cache: %d", i);
+		} else {
+			CAM_INFO(CAM_ISP,
+			"llcc staling feature supported: %d rc = %d", i, rc);
+			g_ife_hw_mgr.sys_cache_info[i].llcc_staling_support = true;
+		}
 	}
 
 	CAM_DBG(CAM_ISP, "Num SCIDs Small:%u Large: %u", num_small_scid, num_large_scid);
 	for (i = 0; i < num_sfe; i++)
 		CAM_DBG(CAM_ISP, "SFE[%u] available SCIDs 0x%x", i,
 			g_ife_hw_mgr.sfe_cache_info[i].supported_scid_idx);
+	return rc;
+
 }
 
 int cam_ife_hw_mgr_init(struct cam_hw_mgr_intf *hw_mgr_intf, int *iommu_hdl)
@@ -15558,9 +15602,12 @@ int cam_ife_hw_mgr_init(struct cam_hw_mgr_intf *hw_mgr_intf, int *iommu_hdl)
 		CAM_ERR(CAM_ISP, "Unable to create worker, ctx_idx: %u", ctx_pool->ctx_index);
 		goto end;
 	}
-
 	/* Populate sys cache info */
-	cam_ife_mgr_populate_sys_cache_id();
+	rc = cam_ife_mgr_populate_sys_cache_id();
+	if (rc == -EFAULT) {
+		CAM_ERR(CAM_ISP, "LLCC stall notif enable fault");
+		goto end;
+	}
 
 	/* fill return structure */
 	hw_mgr_intf->hw_mgr_priv = &g_ife_hw_mgr;

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

@@ -408,10 +408,12 @@ struct cam_isp_ife_sfe_hw_caps {
  *
  * @type:                    Cache type
  * @scid:                    Cache slice ID
+ * @llcc_staling_support     to check llcc sys cache stalling mode supported or not
  */
 struct cam_isp_sys_cache_info {
 	enum cam_sys_cache_config_types type;
 	int32_t                         scid;
+	bool            llcc_staling_support;
 };
 
 /*