summaryrefslogtreecommitdiff
path: root/drivers/media/platform
diff options
context:
space:
mode:
authorSagar Gore <sgore@codeaurora.org>2016-05-05 17:39:50 -0700
committerGerrit - the friendly Code Review server <code-review@localhost>2016-07-14 16:25:43 -0700
commit414c4e991602e85d7b3878f8f8f663195dc3b446 (patch)
tree404f62132e5bd53c2f0b8bb789c2e8e685202ced /drivers/media/platform
parentaa958278d16faccd0cc79650b94ea6aa18d4131d (diff)
msm: camera: ispif: RDI Pack mode support
Add support for pack mode in ISPIF RDI path. Change-Id: I9472f3162a87b8a4255d9c684573093642d488a2 Signed-off-by: Sagar Gore <sgore@codeaurora.org>
Diffstat (limited to 'drivers/media/platform')
-rw-r--r--drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c199
-rw-r--r--drivers/media/platform/msm/camera_v2/ispif/msm_ispif_hwreg_v1.h8
-rw-r--r--drivers/media/platform/msm/camera_v2/ispif/msm_ispif_hwreg_v2.h7
-rw-r--r--drivers/media/platform/msm/camera_v2/ispif/msm_ispif_hwreg_v3.h42
4 files changed, 246 insertions, 10 deletions
diff --git a/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c b/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c
index 4c0991e0dd26..c9656e748f09 100644
--- a/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c
+++ b/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c
@@ -58,6 +58,9 @@
static int msm_ispif_clk_ahb_enable(struct ispif_device *ispif, int enable);
static int ispif_close_node(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh);
+static long msm_ispif_subdev_ioctl_unlocked(struct v4l2_subdev *sd,
+ unsigned int cmd, void *arg);
+
int msm_ispif_get_clk_info(struct ispif_device *ispif_dev,
struct platform_device *pdev);
@@ -95,6 +98,192 @@ static struct msm_cam_clk_info ispif_8626_reset_clk_info[] = {
{"camss_csi_vfe_clk", NO_SET_RATE},
};
+#ifdef CONFIG_COMPAT
+struct ispif_cfg_data_ext_32 {
+ enum ispif_cfg_type_t cfg_type;
+ compat_caddr_t data;
+ uint32_t size;
+};
+
+#define VIDIOC_MSM_ISPIF_CFG_EXT_COMPAT \
+ _IOWR('V', BASE_VIDIOC_PRIVATE+1, struct ispif_cfg_data_ext_32)
+#endif
+
+static void msm_ispif_get_pack_mask_from_cfg(
+ struct msm_ispif_pack_cfg *pack_cfg,
+ struct msm_ispif_params_entry *entry,
+ uint32_t *pack_mask)
+{
+ int i;
+ uint32_t temp;
+
+ if (WARN_ON(!entry))
+ return;
+
+ memset(pack_mask, 0, sizeof(uint32_t) * 2);
+ for (i = 0; i < entry->num_cids; i++) {
+ temp = (pack_cfg[entry->cids[i]].pack_mode & 0x3)|
+ (pack_cfg[entry->cids[i]].even_odd_sel & 0x1) << 2 |
+ (pack_cfg[entry->cids[i]].pixel_swap_en & 0x1) << 3;
+ temp = (temp & 0xF) << ((entry->cids[i] % CID8) * 4);
+
+ if (entry->cids[i] > CID7)
+ pack_mask[1] |= temp;
+ else
+ pack_mask[0] |= temp;
+ CDBG("%s:num %d cid %d mode %d pack_mask %x %x\n",
+ __func__, entry->num_cids, entry->cids[i],
+ pack_cfg[i].pack_mode,
+ pack_mask[0], pack_mask[1]);
+
+ }
+}
+
+static int msm_ispif_config2(struct ispif_device *ispif,
+ void *data)
+{
+ int rc = 0, i = 0;
+ enum msm_ispif_intftype intftype;
+ enum msm_ispif_vfe_intf vfe_intf;
+ uint32_t pack_cfg_mask[2];
+ struct msm_ispif_param_data_ext *params =
+ (struct msm_ispif_param_data_ext *)data;
+
+ if (WARN_ON(!ispif) || WARN_ON(!params))
+ return -EINVAL;
+
+ if (ispif->ispif_state != ISPIF_POWER_UP) {
+ pr_err("%s: ispif invalid state %d\n", __func__,
+ ispif->ispif_state);
+ rc = -EPERM;
+ return rc;
+ }
+ if (params->num > MAX_PARAM_ENTRIES) {
+ pr_err("%s: invalid param entries %d\n", __func__,
+ params->num);
+ rc = -EINVAL;
+ return rc;
+ }
+
+ for (i = 0; i < params->num; i++) {
+ intftype = params->entries[i].intftype;
+ vfe_intf = params->entries[i].vfe_intf;
+
+ CDBG("%s, num %d intftype %x, vfe_intf %d, csid %d\n", __func__,
+ params->num, intftype, vfe_intf,
+ params->entries[i].csid);
+
+ if ((intftype >= INTF_MAX) ||
+ (vfe_intf >= ispif->vfe_info.num_vfe) ||
+ (ispif->csid_version <= CSID_VERSION_V22 &&
+ (vfe_intf > VFE0))) {
+ pr_err("%s: VFEID %d and CSID version %d mismatch\n",
+ __func__, vfe_intf, ispif->csid_version);
+ return -EINVAL;
+ }
+
+ msm_ispif_get_pack_mask_from_cfg(params->pack_cfg,
+ &params->entries[i], pack_cfg_mask);
+ msm_ispif_cfg_pack_mode(ispif, intftype, vfe_intf,
+ pack_cfg_mask);
+ }
+ return rc;
+}
+
+static long msm_ispif_cmd_ext(struct v4l2_subdev *sd,
+ void *arg)
+{
+ long rc = 0;
+ struct ispif_device *ispif =
+ (struct ispif_device *)v4l2_get_subdevdata(sd);
+ struct ispif_cfg_data_ext pcdata;
+ struct msm_ispif_param_data_ext *params = NULL;
+#ifdef CONFIG_COMPAT
+ struct ispif_cfg_data_ext_32 *pcdata32 =
+ (struct ispif_cfg_data_ext_32 *)arg;
+
+ if (pcdata32 == NULL) {
+ pr_err("Invalid params passed from user\n");
+ return -EINVAL;
+ }
+ pcdata.cfg_type = pcdata32->cfg_type;
+ pcdata.size = pcdata32->size;
+ pcdata.data = compat_ptr(pcdata32->data);
+
+#else
+ struct ispif_cfg_data_ext *pcdata64 =
+ (struct ispif_cfg_data_ext *)arg;
+
+ if (pcdata64 == NULL) {
+ pr_err("Invalid params passed from user\n");
+ return -EINVAL;
+ }
+ pcdata.cfg_type = pcdata64->cfg_type;
+ pcdata.size = pcdata64->size;
+ pcdata.data = pcdata64->data;
+#endif
+ if (pcdata.size != sizeof(struct msm_ispif_param_data_ext)) {
+ pr_err("%s: payload size mismatch\n", __func__);
+ return -EINVAL;
+ }
+
+ params = kzalloc(sizeof(struct msm_ispif_param_data_ext), GFP_KERNEL);
+ if (!params) {
+ CDBG("%s: params alloc failed\n", __func__);
+ return -ENOMEM;
+ }
+ if (copy_from_user(params, (void __user *)(pcdata.data),
+ pcdata.size)) {
+ kfree(params);
+ return -EFAULT;
+ }
+
+ mutex_lock(&ispif->mutex);
+ switch (pcdata.cfg_type) {
+ case ISPIF_CFG2:
+ rc = msm_ispif_config2(ispif, params);
+ msm_ispif_io_dump_reg(ispif);
+ break;
+ default:
+ pr_err("%s: invalid cfg_type\n", __func__);
+ rc = -EINVAL;
+ break;
+ }
+ mutex_unlock(&ispif->mutex);
+ kfree(params);
+ return rc;
+}
+
+#ifdef CONFIG_COMPAT
+static long msm_ispif_subdev_ioctl_compat(struct v4l2_subdev *sd,
+ unsigned int cmd, void *arg)
+{
+ if (WARN_ON(!sd))
+ return -EINVAL;
+
+ switch (cmd) {
+ case VIDIOC_MSM_ISPIF_CFG_EXT_COMPAT:
+ return msm_ispif_cmd_ext(sd, arg);
+
+ default:
+ return msm_ispif_subdev_ioctl_unlocked(sd, cmd, arg);
+ }
+}
+static long msm_ispif_subdev_ioctl(struct v4l2_subdev *sd,
+ unsigned int cmd, void *arg)
+{
+ if (is_compat_task())
+ return msm_ispif_subdev_ioctl_compat(sd, cmd, arg);
+ else
+ return msm_ispif_subdev_ioctl_unlocked(sd, cmd, arg);
+}
+#else
+static long msm_ispif_subdev_ioctl(struct v4l2_subdev *sd,
+ unsigned int cmd, void *arg)
+{
+ return msm_ispif_subdev_ioctl_unlocked(sd, cmd, arg);
+}
+#endif
static void msm_ispif_put_regulator(struct ispif_device *ispif_dev)
{
int i;
@@ -649,7 +838,6 @@ static uint16_t msm_ispif_get_cids_mask_from_cfg(
{
int i;
uint16_t cids_mask = 0;
-
BUG_ON(!entry);
for (i = 0; i < entry->num_cids; i++)
@@ -657,14 +845,15 @@ static uint16_t msm_ispif_get_cids_mask_from_cfg(
return cids_mask;
}
-
static int msm_ispif_config(struct ispif_device *ispif,
- struct msm_ispif_param_data *params)
+ void *data)
{
int rc = 0, i = 0;
uint16_t cid_mask;
enum msm_ispif_intftype intftype;
enum msm_ispif_vfe_intf vfe_intf;
+ struct msm_ispif_param_data *params =
+ (struct msm_ispif_param_data *)data;
BUG_ON(!ispif);
BUG_ON(!params);
@@ -1415,7 +1604,7 @@ static long msm_ispif_cmd(struct v4l2_subdev *sd, void *arg)
}
static struct v4l2_file_operations msm_ispif_v4l2_subdev_fops;
-static long msm_ispif_subdev_ioctl(struct v4l2_subdev *sd,
+static long msm_ispif_subdev_ioctl_unlocked(struct v4l2_subdev *sd,
unsigned int cmd, void *arg)
{
struct ispif_device *ispif =
@@ -1424,6 +1613,8 @@ static long msm_ispif_subdev_ioctl(struct v4l2_subdev *sd,
switch (cmd) {
case VIDIOC_MSM_ISPIF_CFG:
return msm_ispif_cmd(sd, arg);
+ case VIDIOC_MSM_ISPIF_CFG_EXT:
+ return msm_ispif_cmd_ext(sd, arg);
case MSM_SD_NOTIFY_FREEZE: {
ispif->ispif_sof_debug = 0;
ispif->ispif_rdi0_debug = 0;
diff --git a/drivers/media/platform/msm/camera_v2/ispif/msm_ispif_hwreg_v1.h b/drivers/media/platform/msm/camera_v2/ispif/msm_ispif_hwreg_v1.h
index b82fd34f2396..d488ca618537 100644
--- a/drivers/media/platform/msm/camera_v2/ispif/msm_ispif_hwreg_v1.h
+++ b/drivers/media/platform/msm/camera_v2/ispif/msm_ispif_hwreg_v1.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2016, 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
@@ -115,4 +115,10 @@
#define ISPIF_IRQ_GLOBAL_CLEAR_CMD 0x000001
#define ISPIF_STOP_INTF_IMMEDIATELY 0xAAAAAAAA
+
+/* ISPIF RDI pack mode not supported */
+static inline void msm_ispif_cfg_pack_mode(struct ispif_device *ispif,
+ uint8_t intftype, uint8_t vfe_intf, uint32_t *pack_cfg_mask)
+{
+}
#endif /* __MSM_ISPIF_HWREG_V1_H__ */
diff --git a/drivers/media/platform/msm/camera_v2/ispif/msm_ispif_hwreg_v2.h b/drivers/media/platform/msm/camera_v2/ispif/msm_ispif_hwreg_v2.h
index 01dce6d45897..8ae61dc2d4f6 100644
--- a/drivers/media/platform/msm/camera_v2/ispif/msm_ispif_hwreg_v2.h
+++ b/drivers/media/platform/msm/camera_v2/ispif/msm_ispif_hwreg_v2.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2016, 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
@@ -96,4 +96,9 @@
#define ISPIF_STOP_INTF_IMMEDIATELY 0xAAAAAAAA
+/* ISPIF RDI pack mode not supported */
+static inline void msm_ispif_cfg_pack_mode(struct ispif_device *ispif,
+ uint8_t intftype, uint8_t vfe_intf, uint32_t *pack_cfg_mask)
+{
+}
#endif /* __MSM_ISPIF_HWREG_V2_H__ */
diff --git a/drivers/media/platform/msm/camera_v2/ispif/msm_ispif_hwreg_v3.h b/drivers/media/platform/msm/camera_v2/ispif/msm_ispif_hwreg_v3.h
index 343575263816..94cc974441ee 100644
--- a/drivers/media/platform/msm/camera_v2/ispif/msm_ispif_hwreg_v3.h
+++ b/drivers/media/platform/msm/camera_v2/ispif/msm_ispif_hwreg_v3.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2016, 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
@@ -10,8 +10,8 @@
* GNU General Public License for more details.
*/
-#ifndef __MSM_ISPIF_HWREG_V2_H__
-#define __MSM_ISPIF_HWREG_V2_H__
+#ifndef __MSM_ISPIF_HWREG_V3_H__
+#define __MSM_ISPIF_HWREG_V3_H__
/* common registers */
#define ISPIF_RST_CMD_ADDR 0x008
@@ -99,4 +99,38 @@
#define ISPIF_STOP_INTF_IMMEDIATELY 0xAAAAAAAA
-#endif /* __MSM_ISPIF_HWREG_V2_H__ */
+/* ISPIF RDI pack mode support */
+static inline void msm_ispif_cfg_pack_mode(struct ispif_device *ispif,
+ uint8_t intftype, uint8_t vfe_intf, uint32_t *pack_cfg_mask)
+{
+ uint32_t pack_addr[2];
+
+ if (WARN_ON(!ispif))
+ return;
+
+ switch (intftype) {
+ case RDI0:
+ pack_addr[0] = ISPIF_VFE_m_RDI_INTF_n_PACK_0(vfe_intf, 0);
+ pack_addr[1] = ISPIF_VFE_m_RDI_INTF_n_PACK_1(vfe_intf, 0);
+ break;
+ case RDI1:
+ pack_addr[0] = ISPIF_VFE_m_RDI_INTF_n_PACK_0(vfe_intf, 1);
+ pack_addr[1] = ISPIF_VFE_m_RDI_INTF_n_PACK_1(vfe_intf, 1);
+ break;
+ case RDI2:
+ pack_addr[0] = ISPIF_VFE_m_RDI_INTF_n_PACK_0(vfe_intf, 2);
+ pack_addr[1] = ISPIF_VFE_m_RDI_INTF_n_PACK_1(vfe_intf, 2);
+ break;
+ default:
+ pr_debug("%s: pack_mode not supported on intftype=%d\n",
+ __func__, intftype);
+ return;
+ }
+ pr_debug("%s: intftype %d pack_mask %x: 0x%x, %x:0x%x\n",
+ __func__, intftype, pack_addr[0],
+ pack_cfg_mask[0], pack_addr[1],
+ pack_cfg_mask[1]);
+ msm_camera_io_w_mb(pack_cfg_mask[0], ispif->base + pack_addr[0]);
+ msm_camera_io_w_mb(pack_cfg_mask[1], ispif->base + pack_addr[1]);
+}
+#endif /* __MSM_ISPIF_HWREG_V3_H__ */