diff options
author | Linux Build Service Account <lnxbuild@localhost> | 2017-03-11 10:08:13 -0800 |
---|---|---|
committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2017-03-11 10:08:13 -0800 |
commit | 51740526b9b90ef772ba2c3c6b288f0d1688bb10 (patch) | |
tree | 7cacdf22fc15f1a120cd7be8d59ebcd9b04b5aff | |
parent | 7ea0306f704e0d70da546ced35df22bd5ed87a99 (diff) | |
parent | 8739af7361829d26177d91ea09bbbd95f0039642 (diff) |
Merge "msm: camera: isp: support LPM on dualcamera"
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__ */ |