summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinux Build Service Account <lnxbuild@quicinc.com>2018-01-16 10:03:29 -0800
committerGerrit - the friendly Code Review server <code-review@localhost>2018-01-16 10:03:28 -0800
commit874c79ac6bbede6fcc6e83d5bfd7a772db7f23ae (patch)
tree54cbc9fea07ac73c9a2419c738962abd1cb14647
parent371c451d08badeff653441a44b03e63e5f8303b6 (diff)
parenta211778552390eaad1943f8c75d8a131d2f517fa (diff)
Merge "msm: ais: Camera clock voting fixes for LA XO"
-rw-r--r--drivers/media/platform/msm/ais/Makefile1
-rw-r--r--drivers/media/platform/msm/ais/isp/msm_isp47.c11
-rw-r--r--drivers/media/platform/msm/ais/isp/msm_isp_axi_util.c11
-rw-r--r--drivers/media/platform/msm/ais/isp/msm_isp_util.c25
-rw-r--r--drivers/media/platform/msm/ais/ispif/msm_ispif.c18
-rw-r--r--drivers/media/platform/msm/ais/msm_ais_mgr/Makefile5
-rw-r--r--drivers/media/platform/msm/ais/msm_ais_mgr/msm_ais_mgr.c147
-rw-r--r--drivers/media/platform/msm/ais/msm_ais_mgr/msm_ais_mngr.h31
-rw-r--r--drivers/media/platform/msm/ais/sensor/cci/Makefile1
-rw-r--r--drivers/media/platform/msm/ais/sensor/cci/msm_early_cam.c195
-rw-r--r--drivers/media/platform/msm/ais/sensor/cci/msm_early_cam.h5
-rw-r--r--drivers/media/platform/msm/ais/sensor/io/msm_camera_dt_util.c49
-rw-r--r--drivers/media/platform/msm/ais/sensor/io/msm_camera_dt_util.h8
-rw-r--r--drivers/media/platform/msm/ais/sensor/msm_sensor.c52
-rw-r--r--include/uapi/media/ais/Kbuild1
-rw-r--r--include/uapi/media/ais/msm_ais.h1
-rw-r--r--include/uapi/media/ais/msm_ais_mgr.h28
-rw-r--r--include/uapi/media/ais/msm_ais_sensor.h5
18 files changed, 565 insertions, 29 deletions
diff --git a/drivers/media/platform/msm/ais/Makefile b/drivers/media/platform/msm/ais/Makefile
index b09636a72413..4387b96f01d0 100644
--- a/drivers/media/platform/msm/ais/Makefile
+++ b/drivers/media/platform/msm/ais/Makefile
@@ -21,4 +21,5 @@ obj-$(CONFIG_MSM_AIS) += ispif/
obj-$(CONFIG_MSM_AIS_JPEG) += jpeg_10/
obj-$(CONFIG_MSM_AIS_JPEGDMA) += jpeg_dma/
obj-$(CONFIG_MSM_AIS) += msm_buf_mgr/
+obj-$(CONFIG_MSM_AIS) += msm_ais_mgr/
obj-$(CONFIG_MSM_AIS_FD) += fd/
diff --git a/drivers/media/platform/msm/ais/isp/msm_isp47.c b/drivers/media/platform/msm/ais/isp/msm_isp47.c
index 04e879fc3bcf..1215713ea8c2 100644
--- a/drivers/media/platform/msm/ais/isp/msm_isp47.c
+++ b/drivers/media/platform/msm/ais/isp/msm_isp47.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2018, 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
@@ -306,19 +306,12 @@ int msm_vfe47_init_hardware(struct vfe_device *vfe_dev)
vfe_dev->common_data->dual_vfe_res->vfe_base[vfe_dev->pdev->id] =
vfe_dev->vfe_base;
- rc = msm_isp_update_bandwidth(ISP_VFE0 + vfe_dev->pdev->id,
- MSM_ISP_MIN_AB, MSM_ISP_MIN_IB);
- if (rc)
- goto bw_enable_fail;
-
rc = msm_camera_enable_irq(vfe_dev->vfe_irq, 1);
if (rc < 0)
goto irq_enable_fail;
return rc;
irq_enable_fail:
- msm_isp_update_bandwidth(ISP_VFE0 + vfe_dev->pdev->id, 0, 0);
-bw_enable_fail:
vfe_dev->common_data->dual_vfe_res->vfe_base[vfe_dev->pdev->id] = NULL;
if (cam_config_ahb_clk(NULL, 0, id, CAM_AHB_SUSPEND_VOTE) < 0)
pr_err("%s: failed to remove vote for AHB\n", __func__);
@@ -347,8 +340,6 @@ void msm_vfe47_release_hardware(struct vfe_device *vfe_dev)
vfe_dev->common_data->dual_vfe_res->vfe_base[vfe_dev->pdev->id] = NULL;
- msm_isp_update_bandwidth(ISP_VFE0 + vfe_dev->pdev->id, 0, 0);
-
if (vfe_dev->pdev->id == 0)
id = CAM_AHB_CLIENT_VFE0;
else
diff --git a/drivers/media/platform/msm/ais/isp/msm_isp_axi_util.c b/drivers/media/platform/msm/ais/isp/msm_isp_axi_util.c
index a85ee30769c4..c0a36843d7ff 100644
--- a/drivers/media/platform/msm/ais/isp/msm_isp_axi_util.c
+++ b/drivers/media/platform/msm/ais/isp/msm_isp_axi_util.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2018, 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
@@ -1106,9 +1106,11 @@ void msm_isp_calculate_bandwidth(
int bpp = 0;
if (stream_info->stream_src < RDI_INTF_0) {
+ stream_info->max_width = max(stream_info->max_width,
+ axi_data->src_info[VFE_PIX_0].width);
stream_info->bandwidth =
- (axi_data->src_info[VFE_PIX_0].pixel_clock /
- axi_data->src_info[VFE_PIX_0].width) *
+ (axi_data->src_info[VFE_PIX_0].pixel_clock *
+ axi_data->src_info[VFE_PIX_0].width) /
stream_info->max_width;
stream_info->bandwidth = (unsigned long)stream_info->bandwidth *
stream_info->format_factor / ISP_Q2;
@@ -2272,8 +2274,7 @@ int msm_isp_update_stream_bandwidth(struct vfe_device *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));
+ total_bandwidth, total_bandwidth);
if (rc < 0)
pr_err("%s: update failed\n", __func__);
diff --git a/drivers/media/platform/msm/ais/isp/msm_isp_util.c b/drivers/media/platform/msm/ais/isp/msm_isp_util.c
index 9e5317eb2920..0f749ec03132 100644
--- a/drivers/media/platform/msm/ais/isp/msm_isp_util.c
+++ b/drivers/media/platform/msm/ais/isp/msm_isp_util.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2018, 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
@@ -2217,6 +2217,7 @@ int msm_isp_open_node(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
{
struct vfe_device *vfe_dev = v4l2_get_subdevdata(sd);
long rc = 0;
+ enum cam_ahb_clk_client id;
ISP_DBG("%s open_cnt %u\n", __func__, vfe_dev->vfe_open_cnt);
@@ -2291,6 +2292,17 @@ int msm_isp_open_node(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
cam_smmu_reg_client_page_fault_handler(
vfe_dev->buf_mgr->iommu_hdl,
msm_vfe_iommu_fault_handler, vfe_dev);
+
+ /* Disable vfe clks and allow device to go XO shutdown mode */
+ if (vfe_dev->pdev->id == 0)
+ id = CAM_AHB_CLIENT_VFE0;
+ else
+ id = CAM_AHB_CLIENT_VFE1;
+ 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->hw_info->vfe_ops.platform_ops.enable_clks(vfe_dev, 0);
+ vfe_dev->hw_info->vfe_ops.platform_ops.enable_regulators(vfe_dev, 0);
+
mutex_unlock(&vfe_dev->core_mutex);
mutex_unlock(&vfe_dev->realtime_mutex);
return 0;
@@ -2313,11 +2325,22 @@ int msm_isp_close_node(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
long rc = 0;
int wm;
struct vfe_device *vfe_dev = v4l2_get_subdevdata(sd);
+ enum cam_ahb_clk_client id;
ISP_DBG("%s E open_cnt %u\n", __func__, vfe_dev->vfe_open_cnt);
mutex_lock(&vfe_dev->realtime_mutex);
mutex_lock(&vfe_dev->core_mutex);
+ /* Enable vfe clks to wake up from XO shutdown mode */
+ if (vfe_dev->pdev->id == 0)
+ id = CAM_AHB_CLIENT_VFE0;
+ else
+ id = CAM_AHB_CLIENT_VFE1;
+ if (cam_config_ahb_clk(NULL, 0, id, CAM_AHB_SVS_VOTE) < 0)
+ pr_err("%s: failed to vote for AHB\n", __func__);
+ vfe_dev->hw_info->vfe_ops.platform_ops.enable_clks(vfe_dev, 1);
+ vfe_dev->hw_info->vfe_ops.platform_ops.enable_regulators(vfe_dev, 1);
+
if (!vfe_dev->vfe_open_cnt) {
pr_err("%s invalid state open cnt %d\n", __func__,
vfe_dev->vfe_open_cnt);
diff --git a/drivers/media/platform/msm/ais/ispif/msm_ispif.c b/drivers/media/platform/msm/ais/ispif/msm_ispif.c
index bb75e69ea215..a72ac566bb8c 100644
--- a/drivers/media/platform/msm/ais/ispif/msm_ispif.c
+++ b/drivers/media/platform/msm/ais/ispif/msm_ispif.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2018, 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
@@ -1437,13 +1437,6 @@ static int msm_ispif_init(struct ispif_device *ispif,
return -ENOMEM;
}
- rc = cam_config_ahb_clk(NULL, 0,
- CAM_AHB_CLIENT_ISPIF, CAM_AHB_SVS_VOTE);
- if (rc < 0) {
- pr_err("%s: failed to vote for AHB\n", __func__);
- return rc;
- }
-
rc = msm_ispif_reset_hw(ispif);
if (rc)
goto error_ahb;
@@ -1608,6 +1601,11 @@ static int ispif_open_node(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
rc = msm_camera_enable_irq(ispif->irq, 1);
if (rc)
goto irq_enable_fail;
+
+ /* Disable ispif clk and allow device to go XO shutdown */
+ msm_ispif_clk_ahb_enable(ispif, 0);
+ msm_ispif_set_regulators(ispif->ispif_vdd,
+ ispif->ispif_vdd_count, 0);
}
/* mem remap is done in init when the clock is on */
ispif->open_cnt++;
@@ -1640,6 +1638,10 @@ static int ispif_close_node(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
}
ispif->open_cnt--;
if (ispif->open_cnt == 0) {
+ /* Enable ispif clk to wake up from XO shutdown mode */
+ msm_ispif_clk_ahb_enable(ispif, 1);
+ msm_ispif_set_regulators(ispif->ispif_vdd,
+ ispif->ispif_vdd_count, 1);
msm_ispif_release(ispif);
/* disable clocks and regulator on last close */
msm_ispif_clk_ahb_enable(ispif, 0);
diff --git a/drivers/media/platform/msm/ais/msm_ais_mgr/Makefile b/drivers/media/platform/msm/ais/msm_ais_mgr/Makefile
new file mode 100644
index 000000000000..b7a078738489
--- /dev/null
+++ b/drivers/media/platform/msm/ais/msm_ais_mgr/Makefile
@@ -0,0 +1,5 @@
+ccflags-y += -Idrivers/media/platform/msm/ais
+ccflags-y += -Idrivers/media/platform/msm/ais/common
+ccflags-y += -Idrivers/media/platform/msm/ais/sensor/io
+ccflags-y += -Idrivers/media/platform/msm/ais/sensor/cci
+obj-$(CONFIG_MSM_AIS) += msm_ais_mgr.o
diff --git a/drivers/media/platform/msm/ais/msm_ais_mgr/msm_ais_mgr.c b/drivers/media/platform/msm/ais/msm_ais_mgr/msm_ais_mgr.c
new file mode 100644
index 000000000000..9391c1d0d4ab
--- /dev/null
+++ b/drivers/media/platform/msm/ais/msm_ais_mgr/msm_ais_mgr.c
@@ -0,0 +1,147 @@
+/* Copyright (c) 2018, 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
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#define pr_fmt(fmt) "CAM-BUFMGR %s:%d " fmt, __func__, __LINE__
+
+#include <media/ais/msm_ais_mgr.h>
+#include "msm_ais_mngr.h"
+#include "msm_early_cam.h"
+
+#undef CDBG
+#define CDBG(fmt, args...) pr_debug(fmt, ##args)
+
+static struct msm_ais_mngr_device *msm_ais_mngr_dev;
+
+static long msm_ais_hndl_ioctl(struct v4l2_subdev *sd, void *arg)
+{
+ long rc = 0;
+ struct clk_mgr_cfg_data *pcdata = (struct clk_mgr_cfg_data *)arg;
+ struct msm_ais_mngr_device *clk_mngr_dev =
+ (struct msm_ais_mngr_device *)v4l2_get_subdevdata(sd);
+
+ if (WARN_ON(!clk_mngr_dev) || WARN_ON(!pcdata)) {
+ rc = -EINVAL;
+ return rc;
+ }
+
+ mutex_lock(&clk_mngr_dev->cont_mutex);
+ CDBG(pr_fmt("cfg_type = %d\n"), pcdata->cfg_type);
+ switch (pcdata->cfg_type) {
+ case AIS_CLK_ENABLE:
+ rc = msm_ais_enable_clocks();
+ break;
+ case AIS_CLK_DISABLE:
+ rc = msm_ais_disable_clocks();
+ break;
+
+ default:
+ pr_err("invalid cfg_type\n");
+ rc = -EINVAL;
+ }
+ mutex_unlock(&clk_mngr_dev->cont_mutex);
+ return rc;
+}
+
+static long msm_ais_mngr_subdev_ioctl(struct v4l2_subdev *sd,
+ unsigned int cmd, void *arg)
+{
+ int32_t rc = 0;
+
+ CDBG(pr_fmt("Enter\n"));
+ switch (cmd) {
+ case VIDIOC_MSM_AIS_CLK_CFG:
+ rc = msm_ais_hndl_ioctl(sd, arg);
+ if (rc)
+ pr_err("msm_ais_mngr_subdev_ioctl failed\n");
+ break;
+ default:
+ rc = -ENOIOCTLCMD;
+ }
+ CDBG(pr_fmt("Exit\n"));
+ return rc;
+}
+
+static struct v4l2_subdev_core_ops msm_ais_mngr_subdev_core_ops = {
+ .ioctl = msm_ais_mngr_subdev_ioctl,
+};
+
+static const struct v4l2_subdev_ops msm_ais_mngr_subdev_ops = {
+ .core = &msm_ais_mngr_subdev_core_ops,
+};
+
+static struct v4l2_file_operations msm_ais_v4l2_subdev_fops;
+
+static long msm_clkmgr_subdev_do_ioctl(
+ struct file *file, unsigned int cmd, void *arg)
+{
+ struct video_device *vdev = video_devdata(file);
+ struct v4l2_subdev *sd = vdev_to_v4l2_subdev(vdev);
+
+ return v4l2_subdev_call(sd, core, ioctl, cmd, arg);
+}
+
+
+static long msm_ais_subdev_fops_ioctl(struct file *file, unsigned int cmd,
+ unsigned long arg)
+{
+ return video_usercopy(file, cmd, arg, msm_clkmgr_subdev_do_ioctl);
+}
+
+static int32_t __init msm_ais_mngr_init(void)
+{
+ int32_t rc = 0;
+
+ msm_ais_mngr_dev = kzalloc(sizeof(*msm_ais_mngr_dev),
+ GFP_KERNEL);
+ if (!msm_ais_mngr_dev)
+ return -ENOMEM;
+
+ /* Sub-dev */
+ v4l2_subdev_init(&msm_ais_mngr_dev->subdev.sd,
+ &msm_ais_mngr_subdev_ops);
+ msm_cam_copy_v4l2_subdev_fops(&msm_ais_v4l2_subdev_fops);
+ msm_ais_v4l2_subdev_fops.unlocked_ioctl = msm_ais_subdev_fops_ioctl;
+
+ snprintf(msm_ais_mngr_dev->subdev.sd.name,
+ ARRAY_SIZE(msm_ais_mngr_dev->subdev.sd.name), "msm_ais_mngr");
+ msm_ais_mngr_dev->subdev.sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+ v4l2_set_subdevdata(&msm_ais_mngr_dev->subdev.sd, msm_ais_mngr_dev);
+
+ media_entity_init(&msm_ais_mngr_dev->subdev.sd.entity, 0, NULL, 0);
+ msm_ais_mngr_dev->subdev.sd.entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
+ msm_ais_mngr_dev->subdev.sd.entity.group_id =
+ MSM_CAMERA_SUBDEV_AIS_MNGR;
+ msm_ais_mngr_dev->subdev.close_seq = MSM_SD_CLOSE_4TH_CATEGORY;
+ rc = msm_sd_register(&msm_ais_mngr_dev->subdev);
+ if (rc != 0) {
+ pr_err("msm_sd_register error = %d\n", rc);
+ kfree(msm_ais_mngr_dev);
+ return rc;
+ }
+
+ msm_ais_mngr_dev->subdev.sd.devnode->fops = &msm_ais_v4l2_subdev_fops;
+ mutex_init(&msm_ais_mngr_dev->cont_mutex);
+
+ return rc;
+}
+
+static void __exit msm_ais_mngr_exit(void)
+{
+ msm_sd_unregister(&msm_ais_mngr_dev->subdev);
+ mutex_destroy(&msm_ais_mngr_dev->cont_mutex);
+ kfree(msm_ais_mngr_dev);
+}
+
+module_init(msm_ais_mngr_init);
+module_exit(msm_ais_mngr_exit);
+MODULE_DESCRIPTION("MSM AIS Manager");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/platform/msm/ais/msm_ais_mgr/msm_ais_mngr.h b/drivers/media/platform/msm/ais/msm_ais_mgr/msm_ais_mngr.h
new file mode 100644
index 000000000000..a41a2ca7a48c
--- /dev/null
+++ b/drivers/media/platform/msm/ais/msm_ais_mgr/msm_ais_mngr.h
@@ -0,0 +1,31 @@
+/* Copyright (c) 2018, 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
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __MSM_CLK_GENERIC_MNGR_H__
+#define __MSM_CLK_GENERIC_MNGR_H__
+
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <media/v4l2-subdev.h>
+#include <media/ais/msm_ais.h>
+
+#include "msm.h"
+#include "msm_sd.h"
+
+struct msm_ais_mngr_device {
+ struct msm_sd_subdev subdev;
+ struct mutex cont_mutex;
+};
+
+#endif
diff --git a/drivers/media/platform/msm/ais/sensor/cci/Makefile b/drivers/media/platform/msm/ais/sensor/cci/Makefile
index b8b8c83bc6de..2bb64c16f67d 100644
--- a/drivers/media/platform/msm/ais/sensor/cci/Makefile
+++ b/drivers/media/platform/msm/ais/sensor/cci/Makefile
@@ -1,5 +1,6 @@
ccflags-y += -Idrivers/media/platform/msm/ais
ccflags-y += -Idrivers/media/platform/msm/ais/common
ccflags-y += -Idrivers/media/platform/msm/ais/sensor/io
+ccflags-y += -Idrivers/media/platform/msm/ais/sensor/cci
obj-$(CONFIG_MSM_AIS) += msm_cci.o
obj-$(CONFIG_MSM_AIS) += msm_early_cam.o
diff --git a/drivers/media/platform/msm/ais/sensor/cci/msm_early_cam.c b/drivers/media/platform/msm/ais/sensor/cci/msm_early_cam.c
index 00ec613e7303..fa7a93345575 100644
--- a/drivers/media/platform/msm/ais/sensor/cci/msm_early_cam.c
+++ b/drivers/media/platform/msm/ais/sensor/cci/msm_early_cam.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2018, 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
@@ -113,6 +113,199 @@ int msm_early_cam_disable_clocks(void)
return 0;
}
+
+int msm_ais_enable_clocks(void)
+{
+ int rc = 0;
+
+ CDBG("%s:\n", __func__);
+ /* Vote ON for clocks */
+ if (new_early_cam_dev == NULL) {
+ rc = -EINVAL;
+ pr_err("%s: clock structure uninitialised %d\n", __func__,
+ rc);
+ return rc;
+ }
+
+ /* Vote for camera abh clocks */
+ rc = cam_config_ahb_clk(NULL, 0, CAM_AHB_CLIENT_CSIPHY,
+ CAM_AHB_SVS_VOTE);
+ if (rc < 0) {
+ pr_err("%s: failed to vote for AHB\n", __func__);
+ return rc;
+ }
+
+ rc = cam_config_ahb_clk(NULL, 0, CAM_AHB_CLIENT_CSID,
+ CAM_AHB_SVS_VOTE);
+ if (rc < 0) {
+ pr_err("%s: failed to vote for AHB\n", __func__);
+ return rc;
+ }
+
+ rc = cam_config_ahb_clk(NULL, 0, CAM_AHB_CLIENT_ISPIF,
+ CAM_AHB_SVS_VOTE);
+ if (rc < 0) {
+ pr_err("%s: failed to vote for AHB\n", __func__);
+ return rc;
+ }
+
+ rc = cam_config_ahb_clk(NULL, 0, CAM_AHB_CLIENT_VFE0,
+ CAM_AHB_SVS_VOTE);
+ if (rc < 0) {
+ pr_err("%s: failed to vote for AHB\n", __func__);
+ return rc;
+ }
+
+ rc = cam_config_ahb_clk(NULL, 0, CAM_AHB_CLIENT_VFE1,
+ CAM_AHB_SVS_VOTE);
+ if (rc < 0) {
+ pr_err("%s: failed to vote for AHB\n", __func__);
+ return rc;
+ }
+
+ if (new_early_cam_dev->pdev->dev.of_node)
+ of_property_read_u32((&new_early_cam_dev->pdev->dev)->of_node,
+ "cell-index", &new_early_cam_dev->pdev->id);
+
+ rc = msm_camera_get_clk_info_and_rates(new_early_cam_dev->pdev,
+ &new_early_cam_dev->early_cam_clk_info,
+ &new_early_cam_dev->early_cam_clk,
+ &new_early_cam_dev->early_cam_clk_rates,
+ &new_early_cam_dev->num_clk_cases,
+ &new_early_cam_dev->num_clk);
+ if (rc < 0) {
+ pr_err("%s: msm_early_cam_get_clk_info() failed", __func__);
+ return -EFAULT;
+ }
+
+ rc = msm_camera_get_dt_vreg_data(
+ new_early_cam_dev->pdev->dev.of_node,
+ &(new_early_cam_dev->early_cam_vreg),
+ &(new_early_cam_dev->regulator_count));
+ if (rc < 0) {
+ pr_err("%s: msm_camera_get_dt_vreg_data fail\n", __func__);
+ rc = -EFAULT;
+ return rc;
+ }
+
+ if ((new_early_cam_dev->regulator_count < 0) ||
+ (new_early_cam_dev->regulator_count > MAX_REGULATOR)) {
+ pr_err("%s: invalid reg count = %d, max is %d\n", __func__,
+ new_early_cam_dev->regulator_count, MAX_REGULATOR);
+ rc = -EFAULT;
+ return rc;
+ }
+
+ rc = msm_camera_config_vreg(&new_early_cam_dev->pdev->dev,
+ new_early_cam_dev->early_cam_vreg,
+ new_early_cam_dev->regulator_count,
+ NULL,
+ 0,
+ &new_early_cam_dev->early_cam_reg_ptr[0], 1);
+ if (rc < 0)
+ pr_err("%s:%d early_cam config_vreg failed\n", __func__,
+ __LINE__);
+
+ rc = msm_camera_enable_vreg(&new_early_cam_dev->pdev->dev,
+ new_early_cam_dev->early_cam_vreg,
+ new_early_cam_dev->regulator_count,
+ NULL,
+ 0,
+ &new_early_cam_dev->early_cam_reg_ptr[0], 1);
+ if (rc < 0)
+ pr_err("%s:%d early_cam enable_vreg failed\n", __func__,
+ __LINE__);
+
+ rc = msm_camera_clk_enable(&new_early_cam_dev->pdev->dev,
+ new_early_cam_dev->early_cam_clk_info,
+ new_early_cam_dev->early_cam_clk,
+ new_early_cam_dev->num_clk, true);
+
+ if (rc < 0) {
+ pr_err("%s: clk enable failed %d\n", __func__, rc);
+ rc = 0;
+ return rc;
+ }
+ pr_debug("Turned ON camera clocks\n");
+ return 0;
+
+}
+
+int msm_ais_disable_clocks(void)
+{
+ int rc = 0;
+
+ CDBG("%s:\n", __func__);
+ /* Vote OFF for clocks */
+ if (new_early_cam_dev == NULL) {
+ rc = -EINVAL;
+ pr_err("%s: clock structure uninitialised %d\n", __func__,
+ rc);
+ return rc;
+ }
+
+ if ((new_early_cam_dev->pdev == NULL) ||
+ (new_early_cam_dev->early_cam_clk_info == NULL) ||
+ (new_early_cam_dev->early_cam_clk == NULL) ||
+ (new_early_cam_dev->num_clk == 0)) {
+ rc = -EINVAL;
+ pr_err("%s: Clock details uninitialised %d\n", __func__,
+ rc);
+ return rc;
+ }
+
+ rc = msm_camera_clk_enable(&new_early_cam_dev->pdev->dev,
+ new_early_cam_dev->early_cam_clk_info,
+ new_early_cam_dev->early_cam_clk,
+ new_early_cam_dev->num_clk, false);
+ if (rc < 0) {
+ pr_err("%s: clk disable failed %d\n", __func__, rc);
+ return rc;
+ }
+
+ rc = cam_config_ahb_clk(NULL, 0, CAM_AHB_CLIENT_CSIPHY,
+ CAM_AHB_SUSPEND_VOTE);
+ if (rc < 0) {
+ pr_err("%s: failed to vote OFF AHB_CLIENT_CSIPHY %d\n",
+ __func__, rc);
+ return rc;
+ }
+
+ rc = cam_config_ahb_clk(NULL, 0, CAM_AHB_CLIENT_CSID,
+ CAM_AHB_SUSPEND_VOTE);
+ if (rc < 0) {
+ pr_err("%s: failed to vote OFF AHB_CLIENT_CSID %d\n",
+ __func__, rc);
+ return rc;
+ }
+
+ rc = cam_config_ahb_clk(NULL, 0, CAM_AHB_CLIENT_ISPIF,
+ CAM_AHB_SUSPEND_VOTE);
+ if (rc < 0) {
+ pr_err("%s: failed to vote OFF AHB_CLIENT_ISPIF %d\n",
+ __func__, rc);
+ return rc;
+ }
+
+ rc = cam_config_ahb_clk(NULL, 0, CAM_AHB_CLIENT_VFE0,
+ CAM_AHB_SUSPEND_VOTE);
+ if (rc < 0) {
+ pr_err("%s: failed to vote OFF AHB_CLIENT_VFE0 %d\n",
+ __func__, rc);
+ return rc;
+ }
+
+ rc = cam_config_ahb_clk(NULL, 0, CAM_AHB_CLIENT_VFE1,
+ CAM_AHB_SUSPEND_VOTE);
+ if (rc < 0) {
+ pr_err("%s: failed to vote OFF AHB_CLIENT_VFE0 %d\n",
+ __func__, rc);
+ return rc;
+ }
+ pr_debug("Turned OFF camera clocks\n");
+ return 0;
+
+}
static int msm_early_cam_probe(struct platform_device *pdev)
{
int rc = 0;
diff --git a/drivers/media/platform/msm/ais/sensor/cci/msm_early_cam.h b/drivers/media/platform/msm/ais/sensor/cci/msm_early_cam.h
index a40ab2d1ebc3..e2530d05955c 100644
--- a/drivers/media/platform/msm/ais/sensor/cci/msm_early_cam.h
+++ b/drivers/media/platform/msm/ais/sensor/cci/msm_early_cam.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2018, 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
@@ -20,6 +20,7 @@
#include <linux/workqueue.h>
#include <media/ais/msm_ais_sensor.h>
#include <soc/qcom/ais.h>
+#include <media/ais/msm_ais.h>
#include "msm_sd.h"
#include "cam_soc_api.h"
@@ -50,4 +51,6 @@ struct early_cam_device {
};
int msm_early_cam_disable_clocks(void);
+int msm_ais_enable_clocks(void);
+int msm_ais_disable_clocks(void);
#endif
diff --git a/drivers/media/platform/msm/ais/sensor/io/msm_camera_dt_util.c b/drivers/media/platform/msm/ais/sensor/io/msm_camera_dt_util.c
index d94f082e6765..643ba556db0d 100644
--- a/drivers/media/platform/msm/ais/sensor/io/msm_camera_dt_util.c
+++ b/drivers/media/platform/msm/ais/sensor/io/msm_camera_dt_util.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2018, 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
@@ -1733,3 +1733,50 @@ int msm_camera_power_down(struct msm_camera_power_ctrl_t *ctrl,
return 0;
}
+int msm_camera_cci_power_up(enum msm_camera_device_type_t device_type,
+ struct msm_camera_i2c_client *sensor_i2c_client)
+{
+ int rc = 0;
+
+ CDBG("%s:%d\n", __func__, __LINE__);
+ if (!sensor_i2c_client) {
+ pr_err("failed sensor_i2c_client %pK\n",
+ sensor_i2c_client);
+ return -EINVAL;
+ }
+
+ if (device_type == MSM_CAMERA_PLATFORM_DEVICE) {
+ rc = sensor_i2c_client->i2c_func_tbl->i2c_util(
+ sensor_i2c_client, MSM_CCI_INIT);
+ if (rc < 0) {
+ pr_err("%s cci_init failed\n", __func__);
+ return rc;
+ }
+ }
+ CDBG("%s exit\n", __func__);
+ return rc;
+}
+
+int msm_camera_cci_power_down(enum msm_camera_device_type_t device_type,
+ struct msm_camera_i2c_client *sensor_i2c_client)
+{
+ int rc = 0;
+
+ CDBG("%s:%d\n", __func__, __LINE__);
+ if (!sensor_i2c_client) {
+ pr_err("failed sensor_i2c_client %pK\n",
+ sensor_i2c_client);
+ return -EINVAL;
+ }
+
+ if (device_type == MSM_CAMERA_PLATFORM_DEVICE) {
+ rc = sensor_i2c_client->i2c_func_tbl->i2c_util(
+ sensor_i2c_client, MSM_CCI_RELEASE);
+ if (rc < 0) {
+ pr_err("%s MSM_CCI_RELEASE failed\n", __func__);
+ return rc;
+ }
+ }
+ CDBG("%s exit\n", __func__);
+ return rc;
+}
diff --git a/drivers/media/platform/msm/ais/sensor/io/msm_camera_dt_util.h b/drivers/media/platform/msm/ais/sensor/io/msm_camera_dt_util.h
index fdeeb4aebf00..560a03d34696 100644
--- a/drivers/media/platform/msm/ais/sensor/io/msm_camera_dt_util.h
+++ b/drivers/media/platform/msm/ais/sensor/io/msm_camera_dt_util.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2018, 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
@@ -68,4 +68,10 @@ int msm_cam_sensor_handle_reg_gpio(int seq_val,
int32_t msm_sensor_driver_get_gpio_data(
struct msm_camera_gpio_conf **gpio_conf,
struct device_node *of_node);
+
+int msm_camera_cci_power_up(enum msm_camera_device_type_t device_type,
+ struct msm_camera_i2c_client *sensor_i2c_client);
+
+int msm_camera_cci_power_down(enum msm_camera_device_type_t device_type,
+ struct msm_camera_i2c_client *sensor_i2c_client);
#endif
diff --git a/drivers/media/platform/msm/ais/sensor/msm_sensor.c b/drivers/media/platform/msm/ais/sensor/msm_sensor.c
index 9655fad5b62b..2801fc3ed34e 100644
--- a/drivers/media/platform/msm/ais/sensor/msm_sensor.c
+++ b/drivers/media/platform/msm/ais/sensor/msm_sensor.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2018, 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
@@ -875,6 +875,30 @@ static int msm_sensor_config32(struct msm_sensor_ctrl_t *s_ctrl,
rc = -EFAULT;
}
break;
+ case CFG_CCI_POWER_UP:
+ if (s_ctrl->is_csid_tg_mode)
+ goto DONE;
+
+ rc = msm_camera_cci_power_up(s_ctrl->sensor_device_type,
+ s_ctrl->sensor_i2c_client);
+ if (rc < 0) {
+ pr_err("%s:%d failed rc %d\n", __func__,
+ __LINE__, rc);
+ break;
+ }
+ break;
+ case CFG_CCI_POWER_DOWN:
+ if (s_ctrl->is_csid_tg_mode)
+ goto DONE;
+
+ rc = msm_camera_cci_power_down(s_ctrl->sensor_device_type,
+ s_ctrl->sensor_i2c_client);
+ if (rc < 0) {
+ pr_err("%s:%d failed rc %d\n", __func__,
+ __LINE__, rc);
+ break;
+ }
+ break;
case CFG_SET_STOP_STREAM_SETTING: {
struct msm_camera_i2c_reg_setting32 stop_setting32;
struct msm_camera_i2c_reg_setting *stop_setting =
@@ -1364,6 +1388,32 @@ int msm_sensor_config(struct msm_sensor_ctrl_t *s_ctrl, void *argp)
}
break;
+ case CFG_CCI_POWER_UP:
+ if (s_ctrl->is_csid_tg_mode)
+ goto DONE;
+
+ rc = msm_camera_cci_power_up(s_ctrl->sensor_device_type,
+ s_ctrl->sensor_i2c_client);
+ if (rc < 0) {
+ pr_err("%s:%d failed rc %d\n", __func__,
+ __LINE__, rc);
+ break;
+ }
+ break;
+
+ case CFG_CCI_POWER_DOWN:
+ if (s_ctrl->is_csid_tg_mode)
+ goto DONE;
+
+ rc = msm_camera_cci_power_down(s_ctrl->sensor_device_type,
+ s_ctrl->sensor_i2c_client);
+ if (rc < 0) {
+ pr_err("%s:%d failed rc %d\n", __func__,
+ __LINE__, rc);
+ break;
+ }
+ break;
+
case CFG_SET_STOP_STREAM_SETTING: {
struct msm_camera_i2c_reg_setting *stop_setting =
&s_ctrl->stop_setting;
diff --git a/include/uapi/media/ais/Kbuild b/include/uapi/media/ais/Kbuild
index 121e3a61560f..c8d50c7d077c 100644
--- a/include/uapi/media/ais/Kbuild
+++ b/include/uapi/media/ais/Kbuild
@@ -4,3 +4,4 @@ header-y += msm_ais_isp.h
header-y += msm_ais_ispif.h
header-y += msm_ais_sensor.h
header-y += msm_ais_sensor_sdk.h
+header-y += msm_ais_mgr.h
diff --git a/include/uapi/media/ais/msm_ais.h b/include/uapi/media/ais/msm_ais.h
index 9156ca0c9083..c393a2a7f636 100644
--- a/include/uapi/media/ais/msm_ais.h
+++ b/include/uapi/media/ais/msm_ais.h
@@ -52,6 +52,7 @@
#define MSM_CAMERA_SUBDEV_IR_LED 18
#define MSM_CAMERA_SUBDEV_IR_CUT 19
#define MSM_CAMERA_SUBDEV_EXT 20
+#define MSM_CAMERA_SUBDEV_AIS_MNGR 21
#define MSM_MAX_CAMERA_SENSORS 5
diff --git a/include/uapi/media/ais/msm_ais_mgr.h b/include/uapi/media/ais/msm_ais_mgr.h
new file mode 100644
index 000000000000..43ae16df65f9
--- /dev/null
+++ b/include/uapi/media/ais/msm_ais_mgr.h
@@ -0,0 +1,28 @@
+#ifndef __UAPI_MEDIA_MSM_AIS_MGR_H__
+#define __UAPI_MEDIA_MSM_AIS_MGR_H__
+
+#include <media/ais/msm_ais.h>
+
+enum clk_mgr_cfg_type_t {
+ AIS_CLK_ENABLE,
+ AIS_CLK_DISABLE,
+};
+
+#define AIS_CLK_ENABLE AIS_CLK_ENABLE
+#define AIS_CLK_DISABLE AIS_CLK_DISABLE
+
+struct clk_mgr_cfg_data_ext {
+ enum clk_mgr_cfg_type_t cfg_type;
+};
+
+struct clk_mgr_cfg_data {
+ enum clk_mgr_cfg_type_t cfg_type;
+};
+
+#define VIDIOC_MSM_AIS_CLK_CFG \
+ _IOWR('V', BASE_VIDIOC_PRIVATE, struct clk_mgr_cfg_data)
+
+#define VIDIOC_MSM_AIS_CLK_CFG_EXT \
+ _IOWR('V', BASE_VIDIOC_PRIVATE+1, struct clk_mgr_cfg_data_ext)
+
+#endif /* __UAPI_MEDIA_MSM_AIS_MGR_H__ */
diff --git a/include/uapi/media/ais/msm_ais_sensor.h b/include/uapi/media/ais/msm_ais_sensor.h
index eb9c24024383..59c20c8e84ae 100644
--- a/include/uapi/media/ais/msm_ais_sensor.h
+++ b/include/uapi/media/ais/msm_ais_sensor.h
@@ -369,8 +369,13 @@ enum msm_sensor_cfg_type_t {
CFG_WRITE_I2C_ARRAY_ASYNC,
CFG_WRITE_I2C_ARRAY_SYNC,
CFG_WRITE_I2C_ARRAY_SYNC_BLOCK,
+ CFG_CCI_POWER_UP,
+ CFG_CCI_POWER_DOWN,
};
+#define CFG_CCI_POWER_UP CFG_CCI_POWER_UP
+#define CFG_CCI_POWER_DOWN CFG_CCI_POWER_DOWN
+
enum msm_actuator_cfg_type_t {
CFG_GET_ACTUATOR_INFO,
CFG_SET_ACTUATOR_INFO,