summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinux Build Service Account <lnxbuild@localhost>2017-03-11 10:08:13 -0800
committerGerrit - the friendly Code Review server <code-review@localhost>2017-03-11 10:08:13 -0800
commit51740526b9b90ef772ba2c3c6b288f0d1688bb10 (patch)
tree7cacdf22fc15f1a120cd7be8d59ebcd9b04b5aff
parent7ea0306f704e0d70da546ced35df22bd5ed87a99 (diff)
parent8739af7361829d26177d91ea09bbbd95f0039642 (diff)
Merge "msm: camera: isp: support LPM on dualcamera"
-rw-r--r--drivers/media/platform/msm/camera_v2/isp/msm_isp.h2
-rw-r--r--drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c67
-rw-r--r--drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.h4
-rw-r--r--drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c5
-rw-r--r--include/uapi/media/msmb_isp.h10
5 files changed, 83 insertions, 5 deletions
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp.h b/drivers/media/platform/msm/camera_v2/isp/msm_isp.h
index e54342e3935a..c8cc66a564ce 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp.h
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp.h
@@ -830,6 +830,8 @@ struct vfe_device {
uint32_t recovery_irq1_mask;
/* Store the buf_idx for pd stats RDI stream */
uint8_t pd_buf_idx;
+ /* total bandwidth per vfe */
+ uint64_t total_bandwidth;
};
struct vfe_parent_device {
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c
index 98aa73d0a507..8488405b561a 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c
@@ -2382,7 +2382,6 @@ static int msm_isp_update_stream_bandwidth(struct vfe_device *vfe_dev)
struct msm_vfe_axi_stream *stream_info;
uint64_t total_pix_bandwidth = 0, total_rdi_bandwidth = 0;
uint32_t num_pix_streams = 0;
- uint64_t total_bandwidth = 0;
int vfe_idx;
for (i = 0; i < VFE_AXI_SRC_MAX; i++) {
@@ -2401,10 +2400,10 @@ static int msm_isp_update_stream_bandwidth(struct vfe_device *vfe_dev)
}
}
}
- total_bandwidth = total_pix_bandwidth + total_rdi_bandwidth;
+ vfe_dev->total_bandwidth = total_pix_bandwidth + total_rdi_bandwidth;
rc = msm_isp_update_bandwidth(ISP_VFE0 + vfe_dev->pdev->id,
- (total_bandwidth + vfe_dev->hw_info->min_ab),
- (total_bandwidth + vfe_dev->hw_info->min_ib));
+ (vfe_dev->total_bandwidth + vfe_dev->hw_info->min_ab),
+ (vfe_dev->total_bandwidth + vfe_dev->hw_info->min_ib));
if (rc < 0)
pr_err("%s: update failed\n", __func__);
@@ -2412,6 +2411,66 @@ static int msm_isp_update_stream_bandwidth(struct vfe_device *vfe_dev)
return rc;
}
+int msm_isp_ab_ib_update_lpm_mode(struct vfe_device *vfe_dev, void *arg)
+{
+ int i, rc = 0;
+ uint64_t total_bandwidth = 0;
+ int vfe_idx;
+ unsigned long flags;
+ struct msm_vfe_axi_stream *stream_info;
+ struct msm_vfe_dual_lpm_mode *ab_ib_vote = NULL;
+
+ ab_ib_vote = (struct msm_vfe_dual_lpm_mode *)arg;
+ if (!ab_ib_vote) {
+ pr_err("%s: ab_ib_vote is NULL !!!\n", __func__);
+ rc = -1;
+ return rc;
+ }
+ if (ab_ib_vote->lpm_mode) {
+ for (i = 0; i < ab_ib_vote->num_src; i++) {
+ stream_info =
+ msm_isp_get_stream_common_data(vfe_dev,
+ ab_ib_vote->stream_src[i]);
+ spin_lock_irqsave(&stream_info->lock, flags);
+ if (stream_info->state == ACTIVE) {
+ vfe_idx =
+ msm_isp_get_vfe_idx_for_stream(vfe_dev,
+ stream_info);
+ total_bandwidth +=
+ stream_info->bandwidth[
+ vfe_idx];
+ stream_info->state = PAUSING;
+ }
+ spin_unlock_irqrestore(&stream_info->lock, flags);
+ }
+ vfe_dev->total_bandwidth -= total_bandwidth;
+ rc = msm_isp_update_bandwidth(ISP_VFE0 + vfe_dev->pdev->id,
+ (vfe_dev->total_bandwidth - vfe_dev->hw_info->min_ab),
+ (vfe_dev->total_bandwidth - vfe_dev->hw_info->min_ib));
+ } else {
+ for (i = 0; i < ab_ib_vote->num_src; i++) {
+ stream_info =
+ msm_isp_get_stream_common_data(vfe_dev,
+ ab_ib_vote->stream_src[i]);
+ spin_lock_irqsave(&stream_info->lock, flags);
+ if (stream_info->state == PAUSING) {
+ vfe_idx =
+ msm_isp_get_vfe_idx_for_stream(vfe_dev,
+ stream_info);
+ total_bandwidth +=
+ stream_info->bandwidth[
+ vfe_idx];
+ stream_info->state = ACTIVE;
+ }
+ spin_unlock_irqrestore(&stream_info->lock, flags);
+ }
+ vfe_dev->total_bandwidth += total_bandwidth;
+ rc = msm_isp_update_bandwidth(ISP_VFE0 + vfe_dev->pdev->id,
+ (vfe_dev->total_bandwidth + vfe_dev->hw_info->min_ab),
+ (vfe_dev->total_bandwidth + vfe_dev->hw_info->min_ib));
+ }
+ return rc;
+}
static int msm_isp_init_stream_ping_pong_reg(
struct msm_vfe_axi_stream *stream_info)
{
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.h b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.h
index f9ae5fb74281..65009cb22286 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.h
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -160,4 +160,6 @@ static inline struct msm_vfe_axi_stream *msm_isp_vfe_get_stream(
int msm_isp_cfg_offline_ping_pong_address(struct vfe_device *vfe_dev,
struct msm_vfe_axi_stream *stream_info, uint32_t pingpong_status,
uint32_t buf_idx);
+int msm_isp_ab_ib_update_lpm_mode(struct vfe_device *vfe_dev,
+ void *arg);
#endif /* __MSM_ISP_AXI_UTIL_H__ */
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c
index 86b500973538..22246f613462 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c
@@ -951,6 +951,11 @@ static long msm_isp_ioctl_unlocked(struct v4l2_subdev *sd,
rc = msm_isp_dual_hw_master_slave_sync(vfe_dev, arg);
mutex_unlock(&vfe_dev->core_mutex);
break;
+ case VIDIOC_MSM_ISP_DUAL_HW_LPM_MODE:
+ mutex_lock(&vfe_dev->core_mutex);
+ rc = msm_isp_ab_ib_update_lpm_mode(vfe_dev, arg);
+ mutex_unlock(&vfe_dev->core_mutex);
+ break;
case VIDIOC_MSM_ISP_FETCH_ENG_START:
case VIDIOC_MSM_ISP_MAP_BUF_START_FE:
mutex_lock(&vfe_dev->core_mutex);
diff --git a/include/uapi/media/msmb_isp.h b/include/uapi/media/msmb_isp.h
index fac254c4361b..21fcb3401298 100644
--- a/include/uapi/media/msmb_isp.h
+++ b/include/uapi/media/msmb_isp.h
@@ -842,6 +842,11 @@ struct msm_isp_dual_hw_master_slave_sync {
uint32_t reserved[2];
};
+struct msm_vfe_dual_lpm_mode {
+ enum msm_vfe_axi_stream_src stream_src[VFE_AXI_SRC_MAX];
+ uint32_t num_src;
+ uint32_t lpm_mode;
+};
#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')
@@ -902,6 +907,7 @@ enum msm_isp_ioctl_cmd_code {
MSM_ISP_FETCH_ENG_MULTI_PASS_START,
MSM_ISP_MAP_BUF_START_MULTI_PASS_FE,
MSM_ISP_REQUEST_BUF_VER2,
+ MSM_ISP_DUAL_HW_LPM_MODE,
};
#define VIDIOC_MSM_VFE_REG_CFG \
@@ -1022,4 +1028,8 @@ enum msm_isp_ioctl_cmd_code {
#define VIDIOC_MSM_ISP_REQUEST_BUF_VER2 \
_IOWR('V', MSM_ISP_REQUEST_BUF_VER2, struct msm_isp_buf_request_ver2)
+#define VIDIOC_MSM_ISP_DUAL_HW_LPM_MODE \
+ _IOWR('V', MSM_ISP_DUAL_HW_LPM_MODE, \
+ struct msm_vfe_dual_lpm_mode)
+
#endif /* __MSMB_ISP__ */