소스 검색

msm: camera: cpas: Add support to update camera qos

This change add support to update camera qos statically
and dynamically via hyp.
For each NIU camera driver can call scm API with each NIU's
register offsets, value and number of registers offset that need to be
programed.

CRs-Fixed: 3781697
Change-Id: I42705dd2b379e29f7f32f9c2564cc476dc8c1308
Signed-off-by: Dharmender Sharma <[email protected]>
(cherry picked from commit 15af46a8b65afd9537ec8fc42efde36ad63a33a3)
Dharmender Sharma 1 년 전
부모
커밋
129f32d8e5

+ 33 - 8
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-2023, Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2024, Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include <linux/device.h>
@@ -983,7 +983,8 @@ static int cam_cpas_apply_smart_qos(
 	struct cam_cpas_tree_node *niu_node;
 	struct cam_camnoc_info *camnoc_info;
 	uint8_t i;
-	int32_t reg_indx;
+	int32_t reg_indx, cam_qos_cnt = 0, ret = 0;
+	struct qcom_scm_camera_qos scm_buf[QCOM_SCM_CAMERA_MAX_QOS_CNT] = {0};
 
 	if (cpas_core->smart_qos_dump) {
 		CAM_INFO(CAM_PERF, "Printing SmartQos values before update");
@@ -998,20 +999,44 @@ static int cam_cpas_apply_smart_qos(
 		niu_node = soc_private->smart_qos_info->rt_wr_niu_node[i];
 
 		if (niu_node->curr_priority_high != niu_node->applied_priority_high) {
-			cam_io_w_mb(niu_node->curr_priority_high,
-				soc_info->reg_map[reg_indx].mem_base +
-				niu_node->pri_lut_high_offset);
+			if (!soc_private->enable_secure_qos_update) {
+				cam_io_w_mb(niu_node->curr_priority_high,
+					soc_info->reg_map[reg_indx].mem_base +
+					niu_node->pri_lut_high_offset);
+			} else {
+				scm_buf[cam_qos_cnt].offset = niu_node->pri_lut_high_offset;
+				scm_buf[cam_qos_cnt].val = niu_node->curr_priority_high;
+				cam_qos_cnt++;
+			}
 
 			niu_node->applied_priority_high = niu_node->curr_priority_high;
 		}
 
 		if (niu_node->curr_priority_low != niu_node->applied_priority_low) {
-			cam_io_w_mb(niu_node->curr_priority_low,
-				soc_info->reg_map[reg_indx].mem_base +
-				niu_node->pri_lut_low_offset);
+			if (!soc_private->enable_secure_qos_update) {
+				cam_io_w_mb(niu_node->curr_priority_low,
+					soc_info->reg_map[reg_indx].mem_base +
+					niu_node->pri_lut_low_offset);
+			} else {
+				scm_buf[cam_qos_cnt].offset = niu_node->pri_lut_low_offset;
+				scm_buf[cam_qos_cnt].val = niu_node->curr_priority_low;
+				cam_qos_cnt++;
+			}
 
 			niu_node->applied_priority_low = niu_node->curr_priority_low;
 		}
+
+		if (soc_private->enable_secure_qos_update && cam_qos_cnt) {
+			CAM_DBG(CAM_PERF, "Updating secure camera smartOos count: %d", cam_qos_cnt);
+			ret = cam_update_camnoc_qos_settings(CAM_QOS_UPDATE_TYPE_SMART,
+				cam_qos_cnt, scm_buf);
+			if (ret) {
+				CAM_ERR(CAM_PERF, "Secure camera smartOos update failed:%d", ret);
+				return ret;
+			}
+			CAM_DBG(CAM_PERF, "Updated secure camera smartOos");
+			cam_qos_cnt = 0;
+		}
 	}
 
 	if (cpas_core->smart_qos_dump) {

+ 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-2023, Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2024, Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include <linux/device.h>
@@ -1455,6 +1455,9 @@ int cam_cpas_get_custom_dt_info(struct cam_hw_info *cpas_hw,
 		soc_private->num_vdd_ahb_mapping = count;
 	}
 
+	soc_private->enable_secure_qos_update = of_property_read_bool(of_node,
+			"enable-secure-qos-update");
+
 	soc_private->enable_smart_qos = of_property_read_bool(of_node,
 			"enable-smart-qos");
 

+ 3 - 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-2023, Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2024, Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #ifndef _CAM_CPAS_SOC_H_
@@ -268,6 +268,7 @@ struct cam_cpas_sysfs_info {
  * @num_caches: Number of last level caches
  * @part_info: Camera Hw subpart info
  * @llcc_info: Cache info
+ * @enable_secure_qos_update: whether to program QoS securely on current chipset
  * @enable_smart_qos: Whether to enable Smart QoS mechanism on current chipset
  * @enable_cam_ddr_drv: Whether to enable Camera DDR DRV on current chipset
  * @enable_cam_clk_drv: Whether to enable Camera Clk DRV on current chipset
@@ -303,6 +304,7 @@ struct cam_cpas_private_soc {
 	bool enable_smart_qos;
 	bool enable_cam_ddr_drv;
 	bool enable_cam_clk_drv;
+	bool enable_secure_qos_update;
 	struct cam_cpas_smart_qos_info *smart_qos_info;
 	int32_t icp_clk_index;
 	struct cam_cpas_domain_id_info domain_id_info;

+ 53 - 40
drivers/cam_cpas/cpas_top/cam_cpastop_hw.c

@@ -1040,59 +1040,72 @@ static int cam_cpastop_print_poweron_settings(struct cam_hw_info *cpas_hw)
 
 static int cam_cpastop_poweron(struct cam_hw_info *cpas_hw)
 {
-	int i, j;
+	int i, j, rc = 0;
 	struct cam_cpas_hw_errata_wa_list *errata_wa_list;
 	struct cam_cpas_hw_errata_wa *errata_wa;
 	struct cam_cpas *cpas_core = cpas_hw->core_info;
+	struct cam_cpas_private_soc *soc_private =
+		(struct cam_cpas_private_soc *) cpas_hw->soc_info.soc_private;
 	bool errata_enabled = false;
 
 	for (i = 0; i < cpas_core->num_valid_camnoc; i++)
 		cam_cpastop_reset_irq(0x0, cpas_hw, i);
 
-	for (i = 0; i < cpas_core->num_valid_camnoc; i++) {
-		CAM_DBG(CAM_CPAS, "QOS settings for %s :",
-			camnoc_info[i]->camnoc_name);
-		for (j = 0; j < camnoc_info[i]->specific_size; j++) {
-			if (camnoc_info[i]->specific[j].enable) {
-				CAM_DBG(CAM_CPAS,
-					"Updating QoS settings port: %d prot name: %s",
-					camnoc_info[i]->specific[j].port_type,
-					camnoc_info[i]->specific[j].port_name);
-				cam_cpas_util_reg_update(cpas_hw, camnoc_info[i]->reg_base,
-					&camnoc_info[i]->specific[j].priority_lut_low);
-				cam_cpas_util_reg_update(cpas_hw, camnoc_info[i]->reg_base,
-					&camnoc_info[i]->specific[j].priority_lut_high);
-				cam_cpas_util_reg_update(cpas_hw, camnoc_info[i]->reg_base,
-					&camnoc_info[i]->specific[j].urgency);
-				cam_cpas_util_reg_update(cpas_hw, camnoc_info[i]->reg_base,
-					&camnoc_info[i]->specific[j].danger_lut);
-				cam_cpas_util_reg_update(cpas_hw, camnoc_info[i]->reg_base,
-					&camnoc_info[i]->specific[j].safe_lut);
-				cam_cpas_util_reg_update(cpas_hw, camnoc_info[i]->reg_base,
-					&camnoc_info[i]->specific[j].ubwc_ctl);
-				cam_cpas_util_reg_update(cpas_hw, camnoc_info[i]->reg_base,
-					&camnoc_info[i]->specific[j].flag_out_set0_low);
-				cam_cpas_util_reg_update(cpas_hw, camnoc_info[i]->reg_base,
-					&camnoc_info[i]->specific[j].dynattr_mainctl);
-				cam_cpas_util_reg_update(cpas_hw, camnoc_info[i]->reg_base,
-					&camnoc_info[i]->specific[j].qosgen_mainctl);
-				cam_cpas_util_reg_update(cpas_hw, camnoc_info[i]->reg_base,
-					&camnoc_info[i]->specific[j].qosgen_shaping_low);
-				cam_cpas_util_reg_update(cpas_hw, camnoc_info[i]->reg_base,
-					&camnoc_info[i]->specific[j].qosgen_shaping_high);
+	if (!soc_private->enable_secure_qos_update) {
+		for (i = 0; i < cpas_core->num_valid_camnoc; i++) {
+			CAM_DBG(CAM_CPAS, "QOS settings for %s :",
+				camnoc_info[i]->camnoc_name);
+			for (j = 0; j < camnoc_info[i]->specific_size; j++) {
+				if (camnoc_info[i]->specific[j].enable) {
+					CAM_DBG(CAM_CPAS,
+						"Updating QoS settings port: %d prot name: %s",
+						camnoc_info[i]->specific[j].port_type,
+						camnoc_info[i]->specific[j].port_name);
+
+					cam_cpas_util_reg_update(cpas_hw, camnoc_info[i]->reg_base,
+						&camnoc_info[i]->specific[j].priority_lut_low);
+					cam_cpas_util_reg_update(cpas_hw, camnoc_info[i]->reg_base,
+						&camnoc_info[i]->specific[j].priority_lut_high);
+					cam_cpas_util_reg_update(cpas_hw, camnoc_info[i]->reg_base,
+						&camnoc_info[i]->specific[j].urgency);
+					cam_cpas_util_reg_update(cpas_hw, camnoc_info[i]->reg_base,
+						&camnoc_info[i]->specific[j].danger_lut);
+					cam_cpas_util_reg_update(cpas_hw, camnoc_info[i]->reg_base,
+						&camnoc_info[i]->specific[j].safe_lut);
+					cam_cpas_util_reg_update(cpas_hw, camnoc_info[i]->reg_base,
+						&camnoc_info[i]->specific[j].ubwc_ctl);
+					cam_cpas_util_reg_update(cpas_hw, camnoc_info[i]->reg_base,
+						&camnoc_info[i]->specific[j].flag_out_set0_low);
+					cam_cpas_util_reg_update(cpas_hw, camnoc_info[i]->reg_base,
+						&camnoc_info[i]->specific[j].dynattr_mainctl);
+					cam_cpas_util_reg_update(cpas_hw, camnoc_info[i]->reg_base,
+						&camnoc_info[i]->specific[j].qosgen_mainctl);
+					cam_cpas_util_reg_update(cpas_hw, camnoc_info[i]->reg_base,
+						&camnoc_info[i]->specific[j].qosgen_shaping_low);
+					cam_cpas_util_reg_update(cpas_hw, camnoc_info[i]->reg_base,
+						&camnoc_info[i]->specific[j].qosgen_shaping_high);
+				}
 			}
-		}
 
-		if (!errata_enabled) {
-			errata_wa_list = camnoc_info[i]->errata_wa_list;
-			if (errata_wa_list) {
-				errata_wa = &errata_wa_list->tcsr_camera_hf_sf_ares_glitch;
-				if (errata_wa->enable) {
-					cam_cpastop_scm_write(errata_wa);
-					errata_enabled = true;
+			if (!errata_enabled) {
+				errata_wa_list = camnoc_info[i]->errata_wa_list;
+				if (errata_wa_list) {
+					errata_wa = &errata_wa_list->tcsr_camera_hf_sf_ares_glitch;
+					if (errata_wa->enable) {
+						cam_cpastop_scm_write(errata_wa);
+						errata_enabled = true;
+					}
 				}
 			}
 		}
+	} else {
+		CAM_DBG(CAM_CPAS, "Updating secure camera static QoS settings");
+		rc = cam_update_camnoc_qos_settings(CAM_QOS_UPDATE_TYPE_STATIC, 0, NULL);
+		if (rc) {
+			CAM_ERR(CAM_CPAS, "Secure camera static OoS update failed: %d", rc);
+			return rc;
+		}
+		CAM_DBG(CAM_CPAS, "Updated secure camera static QoS settings");
 	}
 
 	return 0;

+ 9 - 0
drivers/cam_cpas/include/cam_cpas_api.h

@@ -32,6 +32,15 @@
 #define CAM_CPAS_QOS_DEFAULT_SETTINGS_MASK 0x1
 #define CAM_CPAS_QOS_CUSTOM_SETTINGS_MASK  0x2
 
+/**
+ *  Secure camera QoS update id - Enum for identify QOS settings update type
+ */
+enum secure_camera_qos_update_type {
+	CAM_QOS_UPDATE_TYPE_STATIC = 0x0,
+	CAM_QOS_UPDATE_TYPE_SMART  = 0x1,
+	CAM_QOS_UPDATE_TYPE_MAX,
+};
+
 /**
  * enum cam_cpas_regbase_types - Enum for cpas regbase available for clients
  *                             to read/write

+ 15 - 1
drivers/cam_utils/cam_compat.c

@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
  * Copyright (c) 2014-2021, The Linux Foundation. All rights reserved.
- * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include <linux/dma-mapping.h>
@@ -441,6 +441,20 @@ int cam_csiphy_notify_secure_mode(struct csiphy_device *csiphy_dev,
 }
 #endif
 
+int cam_update_camnoc_qos_settings(uint32_t use_case_id,
+	uint32_t qos_cnt, struct qcom_scm_camera_qos *scm_buf)
+{
+	int rc = 0;
+
+	rc = qcom_scm_camera_update_camnoc_qos(use_case_id, qos_cnt, scm_buf);
+	if (rc) {
+		CAM_ERR(CAM_ISP, "scm call to update QoS failed: %d", rc);
+		rc = -EINVAL;
+	}
+
+	return rc;
+}
+
 /* Callback to compare device from match list before adding as component */
 static inline int camera_component_compare_dev(struct device *dev, void *data)
 {

+ 3 - 1
drivers/cam_utils/cam_compat.h

@@ -1,7 +1,7 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
  * Copyright (c) 2014-2021, The Linux Foundation. All rights reserved.
- * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #ifndef _CAM_COMPAT_H_
@@ -61,6 +61,8 @@ struct cam_fw_alloc_info {
 int cam_reserve_icp_fw(struct cam_fw_alloc_info *icp_fw, size_t fw_length);
 void cam_unreserve_icp_fw(struct cam_fw_alloc_info *icp_fw, size_t fw_length);
 void cam_cpastop_scm_write(struct cam_cpas_hw_errata_wa *errata_wa);
+int cam_update_camnoc_qos_settings(uint32_t use_case_id,
+	uint32_t num_arg, struct qcom_scm_camera_qos *scm_buf);
 int cam_ife_notify_safe_lut_scm(bool safe_trigger);
 int camera_component_match_add_drivers(struct device *master_dev,
 	struct component_match **match_list);