msm: camera: isp: Implement new ioctl

Implement a new ioctl that sets the ahb clock vote. This can be
used from user space to make register programming quicker.

CRs-Fixed: 1001335
Change-Id: I1bc0253ada50040d55b57f0ed07ba66b5535106a
Signed-off-by: Shubhraprakash Das <sadas@codeaurora.org>
This commit is contained in:
Shubhraprakash Das 2016-03-07 12:36:57 -08:00 committed by Kyle Yan
parent 15fb7f86a0
commit 2c477301df
9 changed files with 74 additions and 2 deletions

View file

@ -39,4 +39,4 @@ enum cam_ahb_clk_client {
int cam_config_ahb_clk(struct device *dev, unsigned long freq,
enum cam_ahb_clk_client id, enum cam_ahb_clk_vote vote);
int cam_ahb_clk_init(struct platform_device *pdev);
#endif /* _CAM_HW_OPS_H_ */
#endif

View file

@ -28,6 +28,7 @@
#include <linux/msm-bus-board.h>
#include "msm_buf_mgr.h"
#include "cam_hw_ops.h"
#define VFE40_8974V1_VERSION 0x10000018
#define VFE40_8974V2_VERSION 0x1001001A
@ -239,6 +240,8 @@ struct msm_vfe_core_ops {
void (*get_rdi_wm_mask)(struct vfe_device *vfe_dev,
uint32_t *rdi_wm_mask);
bool (*is_module_cfg_lock_needed)(uint32_t reg_offset);
int (*ahb_clk_cfg)(struct vfe_device *vfe_dev,
struct msm_isp_ahb_clk_cfg *ahb_cfg);
};
struct msm_vfe_stats_ops {
int (*get_stats_idx)(enum msm_isp_stats_type stats_type);
@ -703,6 +706,7 @@ struct vfe_device {
uint32_t **vfe_clk_rates;
size_t num_clk;
size_t num_rates;
enum cam_ahb_clk_vote ahb_vote;
/* Sync variables*/
struct completion reset_complete;

View file

@ -1514,6 +1514,7 @@ struct msm_vfe_hardware_info vfe32_hw_info = {
.get_overflow_mask = msm_vfe32_get_overflow_mask,
.is_module_cfg_lock_needed =
msm_vfe32_is_module_cfg_lock_needed,
.ahb_clk_cfg = NULL,
},
.stats_ops = {
.get_stats_idx = msm_vfe32_get_stats_idx,

View file

@ -2256,6 +2256,7 @@ struct msm_vfe_hardware_info vfe40_hw_info = {
.process_error_status = msm_vfe40_process_error_status,
.is_module_cfg_lock_needed =
msm_vfe40_is_module_cfg_lock_needed,
.ahb_clk_cfg = NULL,
},
.stats_ops = {
.get_stats_idx = msm_vfe40_get_stats_idx,

View file

@ -1906,6 +1906,7 @@ struct msm_vfe_hardware_info vfe44_hw_info = {
.process_error_status = msm_vfe44_process_error_status,
.is_module_cfg_lock_needed =
msm_vfe44_is_module_cfg_lock_needed,
.ahb_clk_cfg = NULL,
},
.stats_ops = {
.get_stats_idx = msm_vfe44_get_stats_idx,

View file

@ -2001,6 +2001,7 @@ struct msm_vfe_hardware_info vfe46_hw_info = {
.process_error_status = msm_vfe46_process_error_status,
.is_module_cfg_lock_needed =
msm_vfe46_is_module_cfg_lock_needed,
.ahb_clk_cfg = NULL,
},
.stats_ops = {
.get_stats_idx = msm_vfe46_get_stats_idx,

View file

@ -238,6 +238,43 @@ static int32_t msm_vfe47_init_dt_parms(struct vfe_device *vfe_dev,
return 0;
}
static enum cam_ahb_clk_vote msm_isp47_get_cam_clk_vote(
enum msm_vfe_ahb_clk_vote vote)
{
switch (vote) {
case MSM_ISP_CAMERA_AHB_SVS_VOTE:
return CAM_AHB_SVS_VOTE;
case MSM_ISP_CAMERA_AHB_TURBO_VOTE:
return CAM_AHB_TURBO_VOTE;
case MSM_ISP_CAMERA_AHB_NOMINAL_VOTE:
return CAM_AHB_NOMINAL_VOTE;
case MSM_ISP_CAMERA_AHB_SUSPEND_VOTE:
return CAM_AHB_SUSPEND_VOTE;
}
return 0;
}
static int msm_isp47_ahb_clk_cfg(struct vfe_device *vfe_dev,
struct msm_isp_ahb_clk_cfg *ahb_cfg)
{
int rc = 0;
enum cam_ahb_clk_vote vote;
vote = msm_isp47_get_cam_clk_vote(ahb_cfg->vote);
if (vote && vfe_dev->ahb_vote != vote) {
rc = cam_config_ahb_clk(NULL, 0,
(vfe_dev->pdev->id == ISP_VFE0 ?
CAM_AHB_CLIENT_VFE0 : CAM_AHB_CLIENT_VFE1), vote);
if (rc)
pr_err("%s: failed to set ahb vote to %x\n",
__func__, vote);
else
vfe_dev->ahb_vote = vote;
}
return rc;
}
int msm_vfe47_init_hardware(struct vfe_device *vfe_dev)
{
int rc = -1;
@ -253,6 +290,7 @@ int msm_vfe47_init_hardware(struct vfe_device *vfe_dev)
pr_err("%s: failed to vote for AHB\n", __func__);
goto ahb_vote_fail;
}
vfe_dev->ahb_vote = CAM_AHB_SVS_VOTE;
rc = vfe_dev->hw_info->vfe_ops.platform_ops.enable_regulators(
vfe_dev, 1);
@ -280,6 +318,7 @@ clk_enable_failed:
enable_regulators_failed:
if (cam_config_ahb_clk(NULL, 0, id, CAM_AHB_SUSPEND_VOTE) < 0)
pr_err("%s: failed to remove vote for AHB\n", __func__);
vfe_dev->ahb_vote = CAM_AHB_SUSPEND_VOTE;
ahb_vote_fail:
return rc;
}
@ -312,6 +351,7 @@ void msm_vfe47_release_hardware(struct vfe_device *vfe_dev)
if (cam_config_ahb_clk(NULL, 0, id, CAM_AHB_SUSPEND_VOTE) < 0)
pr_err("%s: failed to vote for AHB\n", __func__);
vfe_dev->ahb_vote = CAM_AHB_SUSPEND_VOTE;
}
void msm_vfe47_init_hardware_reg(struct vfe_device *vfe_dev)
@ -2637,6 +2677,7 @@ struct msm_vfe_hardware_info vfe47_hw_info = {
.process_error_status = msm_vfe47_process_error_status,
.is_module_cfg_lock_needed =
msm_vfe47_is_module_cfg_lock_needed,
.ahb_clk_cfg = msm_isp47_ahb_clk_cfg,
},
.stats_ops = {
.get_stats_idx = msm_vfe47_get_stats_idx,

View file

@ -701,7 +701,6 @@ static int msm_isp_proc_cmd_list(struct vfe_device *vfe_dev, void *arg)
}
#endif /* CONFIG_COMPAT */
static long msm_isp_ioctl_unlocked(struct v4l2_subdev *sd,
unsigned int cmd, void *arg)
{
@ -814,6 +813,15 @@ static long msm_isp_ioctl_unlocked(struct v4l2_subdev *sd,
rc = msm_isp_cfg_input(vfe_dev, arg);
mutex_unlock(&vfe_dev->core_mutex);
break;
case VIDIOC_MSM_ISP_AHB_CLK_CFG:
mutex_lock(&vfe_dev->core_mutex);
if (vfe_dev->hw_info->vfe_ops.core_ops.ahb_clk_cfg)
rc = vfe_dev->hw_info->vfe_ops.core_ops.
ahb_clk_cfg(vfe_dev, arg);
else
rc = -EOPNOTSUPP;
mutex_unlock(&vfe_dev->core_mutex);
break;
case VIDIOC_MSM_ISP_SET_DUAL_HW_MASTER_SLAVE:
mutex_lock(&vfe_dev->core_mutex);
rc = msm_isp_set_dual_HW_master_slave_mode(vfe_dev, arg);

View file

@ -756,6 +756,18 @@ struct msm_isp_event_data {
} u; /* union can have max 52 bytes */
};
enum msm_vfe_ahb_clk_vote {
MSM_ISP_CAMERA_AHB_SVS_VOTE = 1,
MSM_ISP_CAMERA_AHB_TURBO_VOTE = 2,
MSM_ISP_CAMERA_AHB_NOMINAL_VOTE = 3,
MSM_ISP_CAMERA_AHB_SUSPEND_VOTE = 4,
};
struct msm_isp_ahb_clk_cfg {
uint32_t vote;
uint32_t reserved[2];
};
#define V4L2_PIX_FMT_QBGGR8 v4l2_fourcc('Q', 'B', 'G', '8')
#define V4L2_PIX_FMT_QGBRG8 v4l2_fourcc('Q', 'G', 'B', '8')
#define V4L2_PIX_FMT_QGRBG8 v4l2_fourcc('Q', 'G', 'R', '8')
@ -861,4 +873,7 @@ struct msm_isp_event_data {
#define VIDIOC_MSM_ISP_UNMAP_BUF \
_IOWR('V', BASE_VIDIOC_PRIVATE+24, struct msm_isp_unmap_buf_req)
#define VIDIOC_MSM_ISP_AHB_CLK_CFG \
_IOWR('V', BASE_VIDIOC_PRIVATE+25, struct msm_isp_ahb_clk_cfg)
#endif /* __MSMB_ISP__ */