From b8e35c3397f09696cc87e6f2625d3ada6782e87e Mon Sep 17 00:00:00 2001 From: Karthik Anantha Ram Date: Tue, 20 Aug 2019 15:07:50 -0700 Subject: [PATCH] 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 --- drivers/cam_cdm/cam_cdm_core_common.c | 2 +- drivers/cam_cdm/cam_cdm_hw_core.c | 2 +- drivers/cam_cpas/cam_cpas_hw.c | 47 ++++++++++++++++--- drivers/cam_cpas/cam_cpas_hw.h | 7 ++- .../cam_fd/fd_hw_mgr/fd_hw/cam_fd_hw_soc.c | 2 +- drivers/cam_icp/icp_hw/a5_hw/a5_core.c | 7 ++- drivers/cam_icp/icp_hw/bps_hw/bps_core.c | 16 ++++++- drivers/cam_icp/icp_hw/ipe_hw/ipe_core.c | 17 +++++-- .../isp_hw/ife_csid_hw/cam_ife_csid_soc.c | 2 +- .../isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_soc.c | 2 +- .../isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver3.c | 25 ++++++++-- .../jpeg_hw/jpeg_dma_hw/jpeg_dma_core.c | 2 +- .../jpeg_hw/jpeg_enc_hw/jpeg_enc_core.c | 2 +- .../lrme_hw_mgr/lrme_hw/cam_lrme_hw_soc.c | 2 +- .../cam_sensor_module/cam_cci/cam_cci_soc.c | 2 +- .../cam_csiphy/cam_csiphy_core.c | 2 +- 16 files changed, 112 insertions(+), 27 deletions(-) diff --git a/drivers/cam_cdm/cam_cdm_core_common.c b/drivers/cam_cdm/cam_cdm_core_common.c index 5401945c0e23..e903dc805ed0 100644 --- a/drivers/cam_cdm/cam_cdm_core_common.c +++ b/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; diff --git a/drivers/cam_cdm/cam_cdm_hw_core.c b/drivers/cam_cdm/cam_cdm_hw_core.c index 3e84e2049554..7d0515b747a4 100644 --- a/drivers/cam_cdm/cam_cdm_hw_core.c +++ b/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; diff --git a/drivers/cam_cpas/cam_cpas_hw.c b/drivers/cam_cpas/cam_cpas_hw.c index 1a7a5e2b053e..c6dddff25e2c 100644 --- a/drivers/cam_cpas/cam_cpas_hw.c +++ b/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); diff --git a/drivers/cam_cpas/cam_cpas_hw.h b/drivers/cam_cpas/cam_cpas_hw.h index 7b1eda841488..2b02fc411ff4 100644 --- a/drivers/cam_cpas/cam_cpas_hw.h +++ b/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); diff --git a/drivers/cam_fd/fd_hw_mgr/fd_hw/cam_fd_hw_soc.c b/drivers/cam_fd/fd_hw_mgr/fd_hw/cam_fd_hw_soc.c index 56635aa6bce4..d05530ae4e17 100644 --- a/drivers/cam_fd/fd_hw_mgr/fd_hw/cam_fd_hw_soc.c +++ b/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; diff --git a/drivers/cam_icp/icp_hw/a5_hw/a5_core.c b/drivers/cam_icp/icp_hw/a5_hw/a5_core.c index 8c15000c791e..e4cb645b7af0 100644 --- a/drivers/cam_icp/icp_hw/a5_hw/a5_core.c +++ b/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: diff --git a/drivers/cam_icp/icp_hw/bps_hw/bps_core.c b/drivers/cam_icp/icp_hw/bps_hw/bps_core.c index 73075a4ec379..232f29c81db6 100644 --- a/drivers/cam_icp/icp_hw/bps_hw/bps_core.c +++ b/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); diff --git a/drivers/cam_icp/icp_hw/ipe_hw/ipe_core.c b/drivers/cam_icp/icp_hw/ipe_hw/ipe_core.c index 9ea8f51bb914..a0de07833b72 100644 --- a/drivers/cam_icp/icp_hw/ipe_hw/ipe_core.c +++ b/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: diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_soc.c b/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_soc.c index ede6dbc5ea6e..7abcc64068ee 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_soc.c +++ b/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; diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_soc.c b/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_soc.c index cf899e97f326..77e2a059af57 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_soc.c +++ b/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))) { diff --git a/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver3.c b/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver3.c index a4fbe67aa955..743950bd01bc 100644 --- a/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver3.c +++ b/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; } diff --git a/drivers/cam_jpeg/jpeg_hw/jpeg_dma_hw/jpeg_dma_core.c b/drivers/cam_jpeg/jpeg_hw/jpeg_dma_hw/jpeg_dma_core.c index 31b116cc7698..1304bbc71d38 100644 --- a/drivers/cam_jpeg/jpeg_hw/jpeg_dma_hw/jpeg_dma_core.c +++ b/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; diff --git a/drivers/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_core.c b/drivers/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_core.c index 0b7bb7386553..4830bf58e89e 100644 --- a/drivers/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_core.c +++ b/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; diff --git a/drivers/cam_lrme/lrme_hw_mgr/lrme_hw/cam_lrme_hw_soc.c b/drivers/cam_lrme/lrme_hw_mgr/lrme_hw/cam_lrme_hw_soc.c index ba227d2223eb..5ef984cba883 100644 --- a/drivers/cam_lrme/lrme_hw_mgr/lrme_hw/cam_lrme_hw_soc.c +++ b/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; diff --git a/drivers/cam_sensor_module/cam_cci/cam_cci_soc.c b/drivers/cam_sensor_module/cam_cci/cam_cci_soc.c index 633196c983aa..092f42bbe0d9 100644 --- a/drivers/cam_sensor_module/cam_cci/cam_cci_soc.c +++ b/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; diff --git a/drivers/cam_sensor_module/cam_csiphy/cam_csiphy_core.c b/drivers/cam_sensor_module/cam_csiphy/cam_csiphy_core.c index f4bdfff2cb97..6755eb2954ca 100644 --- a/drivers/cam_sensor_module/cam_csiphy/cam_csiphy_core.c +++ b/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;