Browse Source

msm: camera: common: Update AHB vote for camera drivers

As part of cpas start, all drivers will now request for
LOW_SVS as opposed to SVS. The drivers also scale the AHB
vote based on the corresponding HW's src clk voltage.

CRs-Fixed: 2507919
Change-Id: I7fd35e9dd298deb1603812f39d50e4e9390b3aac
Signed-off-by: Karthik Anantha Ram <[email protected]>
Karthik Anantha Ram 5 years ago
parent
commit
b8e35c3397

+ 1 - 1
drivers/cam_cdm/cam_cdm_core_common.c

@@ -274,7 +274,7 @@ int cam_cdm_stream_ops_internal(void *hw_priv,
 			struct cam_axi_vote axi_vote = {0};
 
 			ahb_vote.type = CAM_VOTE_ABSOLUTE;
-			ahb_vote.vote.level = CAM_SVS_VOTE;
+			ahb_vote.vote.level = CAM_LOWSVS_VOTE;
 			axi_vote.num_paths = 1;
 			axi_vote.axi_path[0].path_data_type =
 				CAM_AXI_PATH_DATA_ALL;

+ 1 - 1
drivers/cam_cdm/cam_cdm_hw_core.c

@@ -942,7 +942,7 @@ int cam_hw_cdm_probe(struct platform_device *pdev)
 	cdm_core->cpas_handle = cpas_parms.client_handle;
 
 	ahb_vote.type = CAM_VOTE_ABSOLUTE;
-	ahb_vote.vote.level = CAM_SVS_VOTE;
+	ahb_vote.vote.level = CAM_LOWSVS_VOTE;
 	axi_vote.num_paths = 1;
 	axi_vote.axi_path[0].path_data_type = CAM_AXI_PATH_DATA_ALL;
 	axi_vote.axi_path[0].transac_type = CAM_AXI_TRANSACTION_READ;

+ 41 - 6
drivers/cam_cpas/cam_cpas_hw.c

@@ -932,12 +932,14 @@ static int cam_cpas_util_apply_client_ahb_vote(struct cam_hw_info *cpas_hw,
 
 	CAM_DBG(CAM_CPAS, "Required highest_level[%d]", highest_level);
 
-	rc = cam_cpas_util_vote_bus_client_level(ahb_bus_client,
-		highest_level);
-	if (rc) {
-		CAM_ERR(CAM_CPAS, "Failed in ahb vote, level=%d, rc=%d",
-			highest_level, rc);
-		goto unlock_bus_client;
+	if (cpas_core->ahb_bus_scaling_enable) {
+		rc = cam_cpas_util_vote_bus_client_level(ahb_bus_client,
+			highest_level);
+		if (rc) {
+			CAM_ERR(CAM_CPAS, "Failed in ahb vote, level=%d, rc=%d",
+				highest_level, rc);
+			goto unlock_bus_client;
+		}
 	}
 
 	rc = cam_soc_util_set_clk_rate_level(&cpas_hw->soc_info, highest_level);
@@ -1661,6 +1663,33 @@ static int cam_cpas_util_get_internal_ops(struct platform_device *pdev,
 	return rc;
 }
 
+static int cam_cpas_util_create_debugfs(
+	struct cam_cpas *cpas_core)
+{
+	int rc = 0;
+
+	cpas_core->dentry = debugfs_create_dir("camera_cpas", NULL);
+	if (!cpas_core->dentry)
+		return -ENOMEM;
+
+	if (!debugfs_create_bool("ahb_bus_scaling_enable",
+		0644,
+		cpas_core->dentry,
+		&cpas_core->ahb_bus_scaling_enable)) {
+		CAM_ERR(CAM_CPAS,
+			"failed to create ahb_bus_scaling_enable entry");
+		rc = -ENOMEM;
+		goto err;
+	}
+
+	return 0;
+
+err:
+	debugfs_remove_recursive(cpas_core->dentry);
+	cpas_core->dentry = NULL;
+	return rc;
+}
+
 int cam_cpas_hw_probe(struct platform_device *pdev,
 	struct cam_hw_intf **hw_intf)
 {
@@ -1803,6 +1832,10 @@ int cam_cpas_hw_probe(struct platform_device *pdev,
 	if (rc)
 		goto axi_cleanup;
 
+	rc  = cam_cpas_util_create_debugfs(cpas_core);
+	if (rc)
+		CAM_WARN(CAM_CPAS, "Failed to create dentry");
+
 	*hw_intf = cpas_hw_intf;
 	return 0;
 
@@ -1854,6 +1887,8 @@ int cam_cpas_hw_remove(struct cam_hw_intf *cpas_hw_intf)
 	cam_cpas_util_unregister_bus_client(&cpas_core->ahb_bus_client);
 	cam_cpas_util_client_cleanup(cpas_hw);
 	cam_cpas_soc_deinit_resources(&cpas_hw->soc_info);
+	debugfs_remove_recursive(cpas_core->dentry);
+	cpas_core->dentry = NULL;
 	flush_workqueue(cpas_core->work_queue);
 	destroy_workqueue(cpas_core->work_queue);
 	mutex_destroy(&cpas_hw->hw_mutex);

+ 6 - 1
drivers/cam_cpas/cam_cpas_hw.h

@@ -181,7 +181,10 @@ struct cam_cpas_axi_port {
  * @axi_port: AXI port info for a specific axi index
  * @internal_ops: CPAS HW internal ops
  * @work_queue: Work queue handle
- *
+ * @irq_count: atomic irq count
+ * @irq_count_wq: wait variable to ensure all irq's are handled
+ * @dentry: debugfs file entry
+ * @ahb_bus_scaling_enable: ahb scaling based on src clk corner for bus
  */
 struct cam_cpas {
 	struct cam_cpas_hw_caps hw_caps;
@@ -199,6 +202,8 @@ struct cam_cpas {
 	struct workqueue_struct *work_queue;
 	atomic_t irq_count;
 	wait_queue_head_t irq_count_wq;
+	struct dentry *dentry;
+	bool ahb_bus_scaling_enable;
 };
 
 int cam_camsstop_get_internal_ops(struct cam_cpas_internal_ops *internal_ops);

+ 1 - 1
drivers/cam_fd/fd_hw_mgr/fd_hw/cam_fd_hw_soc.c

@@ -143,7 +143,7 @@ int cam_fd_soc_enable_resources(struct cam_hw_soc_info *soc_info)
 	int rc;
 
 	ahb_vote.type = CAM_VOTE_ABSOLUTE;
-	ahb_vote.vote.level = CAM_SVS_VOTE;
+	ahb_vote.vote.level = CAM_LOWSVS_VOTE;
 	axi_vote.num_paths = 2;
 	axi_vote.axi_path[0].path_data_type = CAM_AXI_PATH_DATA_ALL;
 	axi_vote.axi_path[0].transac_type = CAM_AXI_TRANSACTION_READ;

+ 6 - 1
drivers/cam_icp/icp_hw/a5_hw/a5_core.c

@@ -262,7 +262,7 @@ int cam_a5_init_hw(void *device_priv,
 	a5_soc_info = soc_info->soc_private;
 
 	cpas_vote.ahb_vote.type = CAM_VOTE_ABSOLUTE;
-	cpas_vote.ahb_vote.vote.level = CAM_SVS_VOTE;
+	cpas_vote.ahb_vote.vote.level = CAM_LOWSVS_VOTE;
 	cpas_vote.axi_vote.num_paths = 1;
 	cpas_vote.axi_vote.axi_path[0].path_data_type =
 		CAM_ICP_DEFAULT_AXI_PATH;
@@ -521,6 +521,7 @@ int cam_a5_process_cmd(void *device_priv, uint32_t cmd_type,
 	}
 	case CAM_ICP_A5_CMD_CLK_UPDATE: {
 		int32_t clk_level = 0;
+		struct cam_ahb_vote ahb_vote;
 
 		if (!cmd_args) {
 			CAM_ERR(CAM_ICP, "Invalid args");
@@ -536,6 +537,10 @@ int cam_a5_process_cmd(void *device_priv, uint32_t cmd_type,
 				"Failed to update clk to level: %d rc: %d",
 				clk_level, rc);
 
+		ahb_vote.type = CAM_VOTE_ABSOLUTE;
+		ahb_vote.vote.level = clk_level;
+		cam_cpas_update_ahb_vote(
+			core_info->cpas_handle, &ahb_vote);
 		break;
 	}
 	default:

+ 15 - 1
drivers/cam_icp/icp_hw/bps_hw/bps_core.c

@@ -70,7 +70,7 @@ int cam_bps_init_hw(void *device_priv,
 	}
 
 	cpas_vote.ahb_vote.type = CAM_VOTE_ABSOLUTE;
-	cpas_vote.ahb_vote.vote.level = CAM_SVS_VOTE;
+	cpas_vote.ahb_vote.vote.level = CAM_LOWSVS_VOTE;
 	cpas_vote.axi_vote.num_paths = 1;
 	cpas_vote.axi_vote.axi_path[0].path_data_type =
 		CAM_BPS_DEFAULT_AXI_PATH;
@@ -366,7 +366,9 @@ int cam_bps_process_cmd(void *device_priv, uint32_t cmd_type,
 	case CAM_ICP_BPS_CMD_UPDATE_CLK: {
 		struct cam_a5_clk_update_cmd *clk_upd_cmd =
 			(struct cam_a5_clk_update_cmd *)cmd_args;
+		struct cam_ahb_vote ahb_vote;
 		uint32_t clk_rate = clk_upd_cmd->curr_clk_rate;
+		int32_t clk_level  = 0, err = 0;
 
 		CAM_DBG(CAM_ICP, "bps_src_clk rate = %d", (int)clk_rate);
 
@@ -392,8 +394,20 @@ int cam_bps_process_cmd(void *device_priv, uint32_t cmd_type,
 		rc = cam_bps_update_clk_rate(soc_info, clk_rate);
 		if (rc)
 			CAM_ERR(CAM_ICP, "Failed to update clk");
+
+		err = cam_soc_util_get_clk_level(soc_info,
+			clk_rate, soc_info->src_clk_idx,
+			&clk_level);
+
+		if (!err) {
+			ahb_vote.type = CAM_VOTE_ABSOLUTE;
+			ahb_vote.vote.level = clk_level;
+			cam_cpas_update_ahb_vote(
+				core_info->cpas_handle,
+				&ahb_vote);
 		}
 		break;
+	}
 	case CAM_ICP_BPS_CMD_DISABLE_CLK:
 		if (core_info->clk_enable == true)
 			cam_bps_toggle_clk(soc_info, false);

+ 12 - 5
drivers/cam_icp/icp_hw/ipe_hw/ipe_core.c

@@ -68,7 +68,7 @@ int cam_ipe_init_hw(void *device_priv,
 	}
 
 	cpas_vote.ahb_vote.type = CAM_VOTE_ABSOLUTE;
-	cpas_vote.ahb_vote.vote.level = CAM_SVS_VOTE;
+	cpas_vote.ahb_vote.vote.level = CAM_LOWSVS_VOTE;
 	cpas_vote.axi_vote.num_paths = 1;
 	cpas_vote.axi_vote.axi_path[0].path_data_type =
 		CAM_IPE_DEFAULT_AXI_PATH;
@@ -360,6 +360,7 @@ int cam_ipe_process_cmd(void *device_priv, uint32_t cmd_type,
 	case CAM_ICP_IPE_CMD_UPDATE_CLK: {
 		struct cam_a5_clk_update_cmd *clk_upd_cmd =
 			(struct cam_a5_clk_update_cmd *)cmd_args;
+		struct cam_ahb_vote ahb_vote;
 		uint32_t clk_rate = clk_upd_cmd->curr_clk_rate;
 		int32_t clk_level  = 0, err = 0;
 
@@ -389,11 +390,17 @@ int cam_ipe_process_cmd(void *device_priv, uint32_t cmd_type,
 			CAM_ERR(CAM_ICP, "Failed to update clk");
 
 		err = cam_soc_util_get_clk_level(soc_info,
-				clk_rate, soc_info->src_clk_idx,
-				&clk_level);
-		if (err == 0)
-			clk_upd_cmd->clk_level = clk_level;
+			clk_rate, soc_info->src_clk_idx,
+			&clk_level);
 
+		if (!err) {
+			clk_upd_cmd->clk_level = clk_level;
+			ahb_vote.type = CAM_VOTE_ABSOLUTE;
+			ahb_vote.vote.level = clk_level;
+			cam_cpas_update_ahb_vote(
+				core_info->cpas_handle,
+				&ahb_vote);
+		}
 		break;
 	}
 	case CAM_ICP_IPE_CMD_DISABLE_CLK:

+ 1 - 1
drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_soc.c

@@ -125,7 +125,7 @@ int cam_ife_csid_enable_soc_resources(
 	soc_private = soc_info->soc_private;
 
 	ahb_vote.type = CAM_VOTE_ABSOLUTE;
-	ahb_vote.vote.level = CAM_SVS_VOTE;
+	ahb_vote.vote.level = CAM_LOWSVS_VOTE;
 	axi_vote.num_paths = 1;
 	axi_vote.axi_path[0].path_data_type = CAM_AXI_PATH_DATA_ALL;
 	axi_vote.axi_path[0].transac_type = CAM_AXI_TRANSACTION_WRITE;

+ 1 - 1
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_soc.c

@@ -232,7 +232,7 @@ int cam_vfe_enable_soc_resources(struct cam_hw_soc_info *soc_info)
 	soc_private = soc_info->soc_private;
 
 	ahb_vote.type       = CAM_VOTE_ABSOLUTE;
-	ahb_vote.vote.level = CAM_SVS_VOTE;
+	ahb_vote.vote.level = CAM_LOWSVS_VOTE;
 	axi_vote.num_paths = 1;
 	if (strnstr(soc_info->compatible, "lite",
 		strlen(soc_info->compatible))) {

+ 22 - 3
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver3.c

@@ -82,10 +82,14 @@ static int cam_vfe_top_ver3_set_hw_clk_rate(
 	struct cam_vfe_top_ver3_priv *top_priv)
 {
 	struct cam_hw_soc_info        *soc_info = NULL;
-	int                            i, rc = 0;
+	struct cam_vfe_soc_private    *soc_private = NULL;
+	struct cam_ahb_vote            ahb_vote;
+	int                            i, rc = 0, clk_lvl = -1;
 	unsigned long                  max_clk_rate = 0;
 
 	soc_info = top_priv->common_data.soc_info;
+	soc_private =
+		(struct cam_vfe_soc_private *)soc_info->soc_private;
 
 	for (i = 0; i < top_priv->top_common.num_mux; i++) {
 		if (top_priv->req_clk_rate[i] > max_clk_rate)
@@ -100,11 +104,26 @@ static int cam_vfe_top_ver3_set_hw_clk_rate(
 
 	rc = cam_soc_util_set_src_clk_rate(soc_info, max_clk_rate);
 
-	if (!rc)
+	if (!rc) {
 		top_priv->hw_clk_rate = max_clk_rate;
-	else
+		rc = cam_soc_util_get_clk_level(soc_info, max_clk_rate,
+			soc_info->src_clk_idx, &clk_lvl);
+		if (rc) {
+			CAM_WARN(CAM_ISP,
+				"Failed to get clk level for %s with clk_rate %llu src_idx %d rc %d",
+				soc_info->dev_name, max_clk_rate,
+				soc_info->src_clk_idx, rc);
+			rc = 0;
+			goto end;
+		}
+		ahb_vote.type = CAM_VOTE_ABSOLUTE;
+		ahb_vote.vote.level = clk_lvl;
+		cam_cpas_update_ahb_vote(soc_private->cpas_handle, &ahb_vote);
+	} else {
 		CAM_ERR(CAM_PERF, "Set Clock rate failed, rc=%d", rc);
+	}
 
+end:
 	return rc;
 }
 

+ 1 - 1
drivers/cam_jpeg/jpeg_hw/jpeg_dma_hw/jpeg_dma_core.c

@@ -55,7 +55,7 @@ int cam_jpeg_dma_init_hw(void *device_priv,
 	}
 
 	ahb_vote.type = CAM_VOTE_ABSOLUTE;
-	ahb_vote.vote.level = CAM_SVS_VOTE;
+	ahb_vote.vote.level = CAM_LOWSVS_VOTE;
 	axi_vote.num_paths = 2;
 	axi_vote.axi_path[0].path_data_type = CAM_AXI_PATH_DATA_ALL;
 	axi_vote.axi_path[0].transac_type = CAM_AXI_TRANSACTION_READ;

+ 1 - 1
drivers/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_core.c

@@ -66,7 +66,7 @@ int cam_jpeg_enc_init_hw(void *device_priv,
 	}
 
 	ahb_vote.type = CAM_VOTE_ABSOLUTE;
-	ahb_vote.vote.level = CAM_SVS_VOTE;
+	ahb_vote.vote.level = CAM_LOWSVS_VOTE;
 	axi_vote.num_paths = 2;
 	axi_vote.axi_path[0].path_data_type = CAM_AXI_PATH_DATA_ALL;
 	axi_vote.axi_path[0].transac_type = CAM_AXI_TRANSACTION_READ;

+ 1 - 1
drivers/cam_lrme/lrme_hw_mgr/lrme_hw/cam_lrme_hw_soc.c

@@ -24,7 +24,7 @@ int cam_lrme_soc_enable_resources(struct cam_hw_info *lrme_hw)
 	int rc = 0;
 
 	ahb_vote.type = CAM_VOTE_ABSOLUTE;
-	ahb_vote.vote.level = CAM_SVS_VOTE;
+	ahb_vote.vote.level = CAM_LOWSVS_VOTE;
 	axi_vote.num_paths = 2;
 	axi_vote.axi_path[0].path_data_type = CAM_AXI_PATH_DATA_ALL;
 	axi_vote.axi_path[0].transac_type = CAM_AXI_TRANSACTION_READ;

+ 1 - 1
drivers/cam_sensor_module/cam_cci/cam_cci_soc.c

@@ -73,7 +73,7 @@ int cam_cci_init(struct v4l2_subdev *sd,
 	}
 
 	ahb_vote.type = CAM_VOTE_ABSOLUTE;
-	ahb_vote.vote.level = CAM_SVS_VOTE;
+	ahb_vote.vote.level = CAM_LOWSVS_VOTE;
 	axi_vote.num_paths = 1;
 	axi_vote.axi_path[0].path_data_type =
 		CAM_AXI_PATH_DATA_ALL;

+ 1 - 1
drivers/cam_sensor_module/cam_csiphy/cam_csiphy_core.c

@@ -900,7 +900,7 @@ int32_t cam_csiphy_core_cfg(void *phy_dev,
 		}
 
 		ahb_vote.type = CAM_VOTE_ABSOLUTE;
-		ahb_vote.vote.level = CAM_SVS_VOTE;
+		ahb_vote.vote.level = CAM_LOWSVS_VOTE;
 		axi_vote.num_paths = 1;
 		axi_vote.axi_path[0].path_data_type = CAM_AXI_PATH_DATA_ALL;
 		axi_vote.axi_path[0].transac_type = CAM_AXI_TRANSACTION_WRITE;