浏览代码

Merge "msm: camera: csiphy: Trigger ISP callback on phy clock change" into camera-kernel.lnx.7.0

Wasim Khan 1 年之前
父节点
当前提交
0fc142d2fa

+ 26 - 3
drivers/cam_sensor_module/cam_csiphy/cam_csiphy_core.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/module.h>
@@ -2074,7 +2074,6 @@ int32_t cam_csiphy_core_cfg(void *phy_dev,
 	uint32_t      cphy_trio_status;
 	void __iomem *csiphybase;
 	int32_t              rc = 0;
-	uint32_t             i;
 
 	if (!csiphy_dev || !cmd) {
 		CAM_ERR(CAM_CSIPHY, "Invalid input args");
@@ -2485,10 +2484,11 @@ int32_t cam_csiphy_core_cfg(void *phy_dev,
 	case CAM_START_DEV: {
 		struct cam_csiphy_param *param;
 		struct cam_start_stop_dev_cmd config;
-		int32_t offset;
+		int32_t i, offset;
 		int clk_vote_level_high = -1;
 		int clk_vote_level_low = -1;
 		uint8_t data_rate_variant_idx = 0;
+		unsigned long clk_rate = 0;
 
 		CAM_DBG(CAM_CSIPHY, "START_DEV Called");
 		rc = copy_from_user(&config, (void __user *)cmd->handle,
@@ -2574,6 +2574,29 @@ int32_t cam_csiphy_core_cfg(void *phy_dev,
 					goto release_mutex;
 
 				}
+
+				for (i = 0; i < csiphy_dev->soc_info.num_clk;
+									i++) {
+					if (i ==
+					csiphy_dev->soc_info.src_clk_idx) {
+						CAM_DBG(CAM_CSIPHY,
+						"Skipping call back for src"
+						" clk %s",
+						csiphy_dev->soc_info.clk_name[
+									i]);
+						continue;
+					}
+					clk_rate =
+					cam_soc_util_get_clk_rate_applied(
+						&csiphy_dev->soc_info, i,
+						false, clk_vote_level_high);
+					if (clk_rate > 0) {
+						cam_subdev_notify_message(
+						CAM_TFE_DEVICE_TYPE,
+					CAM_SUBDEV_MESSAGE_CLOCK_UPDATE,
+						(void *)(&clk_rate));
+					}
+				}
 			}
 
 			if (csiphy_dev->csiphy_info[offset].secure_mode == 1) {

+ 27 - 1
drivers/cam_sensor_module/cam_csiphy/cam_csiphy_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) 2021-2023, Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2024, Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include "cam_csiphy_soc.h"
@@ -184,6 +184,7 @@ int32_t cam_csiphy_enable_hw(struct csiphy_device *csiphy_dev, int32_t index)
 	struct cam_hw_soc_info   *soc_info;
 	enum cam_vote_level vote_level;
 	struct cam_csiphy_param *param = &csiphy_dev->csiphy_info[index];
+	unsigned long clk_rate = 0;
 	int i;
 
 	soc_info = &csiphy_dev->soc_info;
@@ -238,6 +239,31 @@ int32_t cam_csiphy_enable_hw(struct csiphy_device *csiphy_dev, int32_t index)
 			goto disable_platform_resource;
 		}
 
+	} else {
+		clk_rate = soc_info->clk_rate[0][soc_info->src_clk_idx];
+		rc = cam_soc_util_set_src_clk_rate(soc_info,
+			CAM_CLK_SW_CLIENT_IDX, clk_rate, 0);
+		if (rc) {
+			CAM_ERR(CAM_CSIPHY, "csiphy_set_src_clk_rate failed"
+				" rc: %d", rc);
+			rc = -EINVAL;
+			goto disable_platform_resource;
+		}
+
+		for (i = 0; i < soc_info->num_clk; i++) {
+			if (i == soc_info->src_clk_idx) {
+				CAM_DBG(CAM_CSIPHY, "Skipping call back"
+				" for src clk %s", soc_info->clk_name[i]);
+				continue;
+			}
+			clk_rate = cam_soc_util_get_clk_rate_applied(soc_info,
+				i, false, vote_level);
+			if (clk_rate > 0) {
+				cam_subdev_notify_message(CAM_TFE_DEVICE_TYPE,
+					CAM_SUBDEV_MESSAGE_CLOCK_UPDATE,
+					(void *)(&clk_rate));
+			}
+		}
 	}
 
 	cam_csiphy_reset(csiphy_dev);

+ 25 - 0
drivers/cam_utils/cam_soc_util.c

@@ -1287,6 +1287,31 @@ static int cam_soc_util_get_clk_level_to_apply(
 	return 0;
 }
 
+unsigned long cam_soc_util_get_clk_rate_applied(
+	struct cam_hw_soc_info *soc_info, int32_t index, bool is_src,
+	enum cam_vote_level clk_level)
+{
+	unsigned long clk_rate = 0;
+	struct clk *clk = NULL;
+	int rc = 0;
+	enum cam_vote_level apply_level;
+
+	if (is_src) {
+		clk = soc_info->clk[index];
+		clk_rate = cam_wrapper_clk_get_rate(clk);
+	} else {
+		rc = cam_soc_util_get_clk_level_to_apply(soc_info, clk_level,
+			&apply_level);
+		if (rc)
+			return rc;
+		if (soc_info->clk_rate[apply_level][index] > 0) {
+			clk = soc_info->clk[index];
+			clk_rate = cam_wrapper_clk_get_rate(clk);
+		}
+	}
+	return clk_rate;
+}
+
 int cam_soc_util_irq_enable(struct cam_hw_soc_info *soc_info)
 {
 	int i, rc = 0;

+ 4 - 0
drivers/cam_utils/cam_soc_util.h

@@ -799,6 +799,10 @@ int cam_soc_util_clk_enable_default(struct cam_hw_soc_info *soc_info, int cesta_
 int cam_soc_util_get_clk_level(struct cam_hw_soc_info *soc_info,
 	int64_t clk_rate, int clk_idx, int32_t *clk_lvl);
 
+unsigned long cam_soc_util_get_clk_rate_applied(
+	struct cam_hw_soc_info *soc_info, int32_t index, bool is_src,
+	enum cam_vote_level clk_level);
+
 /* Callback to get reg space data for specific HW */
 typedef int (*cam_soc_util_regspace_data_cb)(uint32_t reg_base_type,
 	void *ctx, struct cam_hw_soc_info **soc_info_ptr,