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 <kartanan@codeaurora.org>
This commit is contained in:
Karthik Anantha Ram 2019-08-20 15:07:50 -07:00 committed by Gerrit - the friendly Code Review server
parent 3ef8ba0db6
commit b8e35c3397
16 changed files with 112 additions and 27 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -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;

View File

@ -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:

View File

@ -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);

View File

@ -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:

View File

@ -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;

View File

@ -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))) {

View File

@ -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;
}

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;