All of lore.kernel.org
 help / color / mirror / Atom feed
From: Steve Longerbeam <slongerbeam@gmail.com>
To: Philipp Zabel <p.zabel@pengutronix.de>, dri-devel@lists.freedesktop.org
Cc: Steve Longerbeam <steve_longerbeam@mentor.com>,
	Russell King <linux@arm.linux.org.uk>,
	kernel@pengutronix.de
Subject: Re: [PATCH 05/26] gpu: ipu-v3: Add Camera Sensor Interface unit
Date: Tue, 19 Aug 2014 10:52:40 -0700	[thread overview]
Message-ID: <53F38EE8.3020702@gmail.com> (raw)
In-Reply-To: <1408369225-21093-6-git-send-email-p.zabel@pengutronix.de>

On 08/18/2014 06:40 AM, Philipp Zabel wrote:
> From: Steve Longerbeam <slongerbeam@gmail.com>
>
> Adds the Camera Sensor Interface (CSI) unit required for video capture.
>
> Signed-off-by: Steve Longerbeam <steve_longerbeam@mentor.com>
>
> Removed the unused clk_get_rate in ipu_csi_init_interface and the
> ipu_csi_ccir_err_detection_enable/disable functions.
>
> Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
> ---
>  drivers/gpu/ipu-v3/Makefile     |   2 +-
>  drivers/gpu/ipu-v3/ipu-common.c |  44 ++-
>  drivers/gpu/ipu-v3/ipu-csi.c    | 670 ++++++++++++++++++++++++++++++++++++++++
>  drivers/gpu/ipu-v3/ipu-prv.h    |   6 +
>  include/video/imx-ipu-v3.h      |  68 +++-
>  5 files changed, 775 insertions(+), 15 deletions(-)
>  create mode 100644 drivers/gpu/ipu-v3/ipu-csi.c
>
>

Hi Phillip,

Recently I've added motion compensated deinterlacing support via the VDIC to
our version of the imx capture driver for a customer, and in the process of
that effort I needed to modify the API to ipu-csi a bit, specifically to
ipu_csi_set_dest() to allow specifying the VDIC as a CSI destination.

Also, to reduce the namespace in include/video/imx-ipu-v3.h, and more
data-hiding in general, I'd like to propose changing the args to
ipu_csi_init_interface() so that struct ipu_csi_signal_cfg (and related
enumerations) can be made private to ipu-csi.

A version 2 of this patch follows.

Steve


>From 11e06801013ee5d76e32651735132fce50ad7f08 Mon Sep 17 00:00:00 2001
From: Steve Longerbeam <slongerbeam@gmail.com>
Date: Mon, 18 Aug 2014 15:40:04 +0200
Subject: [PATCH 05/26] gpu: ipu-v3: Add Camera Sensor Interface unit

Adds the Camera Sensor Interface (CSI) unit required for video capture.

Signed-off-by: Steve Longerbeam <steve_longerbeam@mentor.com>

Removed the unused clk_get_rate in ipu_csi_init_interface and the
ipu_csi_ccir_err_detection_enable/disable functions.

Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
---
 drivers/gpu/ipu-v3/Makefile     |    2 +-
 drivers/gpu/ipu-v3/ipu-common.c |   44 ++-
 drivers/gpu/ipu-v3/ipu-csi.c    |  768 +++++++++++++++++++++++++++++++++++++++
 drivers/gpu/ipu-v3/ipu-prv.h    |    6 +
 include/video/imx-ipu-v3.h      |   32 +-
 5 files changed, 837 insertions(+), 15 deletions(-)
 create mode 100644 drivers/gpu/ipu-v3/ipu-csi.c

diff --git a/drivers/gpu/ipu-v3/Makefile b/drivers/gpu/ipu-v3/Makefile
index 0b42836..d22bd06 100644
--- a/drivers/gpu/ipu-v3/Makefile
+++ b/drivers/gpu/ipu-v3/Makefile
@@ -1,4 +1,4 @@
 obj-$(CONFIG_IMX_IPUV3_CORE) += imx-ipu-v3.o
 
-imx-ipu-v3-objs := ipu-common.o ipu-cpmem.o ipu-dc.o ipu-di.o \
+imx-ipu-v3-objs := ipu-common.o ipu-cpmem.o ipu-csi.o ipu-dc.o ipu-di.o \
         ipu-dp.o ipu-dmfc.o ipu-smfc.o
diff --git a/drivers/gpu/ipu-v3/ipu-common.c b/drivers/gpu/ipu-v3/ipu-common.c
index cae5431..511c364 100644
--- a/drivers/gpu/ipu-v3/ipu-common.c
+++ b/drivers/gpu/ipu-v3/ipu-common.c
@@ -217,18 +217,6 @@ int ipu_module_disable(struct ipu_soc *ipu, u32 mask)
 }
 EXPORT_SYMBOL_GPL(ipu_module_disable);
 
-int ipu_csi_enable(struct ipu_soc *ipu, int csi)
-{
-    return ipu_module_enable(ipu, csi ? IPU_CONF_CSI1_EN : IPU_CONF_CSI0_EN);
-}
-EXPORT_SYMBOL_GPL(ipu_csi_enable);
-
-int ipu_csi_disable(struct ipu_soc *ipu, int csi)
-{
-    return ipu_module_disable(ipu, csi ? IPU_CONF_CSI1_EN : IPU_CONF_CSI0_EN);
-}
-EXPORT_SYMBOL_GPL(ipu_csi_disable);
-
 int ipu_smfc_enable(struct ipu_soc *ipu)
 {
     return ipu_module_enable(ipu, IPU_CONF_SMFC_EN);
@@ -439,6 +427,8 @@ struct ipu_devtype {
     unsigned long cpmem_ofs;
     unsigned long srm_ofs;
     unsigned long tpm_ofs;
+    unsigned long csi0_ofs;
+    unsigned long csi1_ofs;
     unsigned long disp0_ofs;
     unsigned long disp1_ofs;
     unsigned long dc_tmpl_ofs;
@@ -452,6 +442,8 @@ static struct ipu_devtype ipu_type_imx51 = {
     .cpmem_ofs = 0x1f000000,
     .srm_ofs = 0x1f040000,
     .tpm_ofs = 0x1f060000,
+    .csi0_ofs = 0x1f030000,
+    .csi1_ofs = 0x1f038000,
     .disp0_ofs = 0x1e040000,
     .disp1_ofs = 0x1e048000,
     .dc_tmpl_ofs = 0x1f080000,
@@ -465,6 +457,8 @@ static struct ipu_devtype ipu_type_imx53 = {
     .cpmem_ofs = 0x07000000,
     .srm_ofs = 0x07040000,
     .tpm_ofs = 0x07060000,
+    .csi0_ofs = 0x07030000,
+    .csi1_ofs = 0x07038000,
     .disp0_ofs = 0x06040000,
     .disp1_ofs = 0x06048000,
     .dc_tmpl_ofs = 0x07080000,
@@ -478,6 +472,8 @@ static struct ipu_devtype ipu_type_imx6q = {
     .cpmem_ofs = 0x00300000,
     .srm_ofs = 0x00340000,
     .tpm_ofs = 0x00360000,
+    .csi0_ofs = 0x00230000,
+    .csi1_ofs = 0x00238000,
     .disp0_ofs = 0x00240000,
     .disp1_ofs = 0x00248000,
     .dc_tmpl_ofs = 0x00380000,
@@ -508,6 +504,20 @@ static int ipu_submodules_init(struct ipu_soc *ipu,
         goto err_cpmem;
     }
 
+    ret = ipu_csi_init(ipu, dev, 0, ipu_base + devtype->csi0_ofs,
+               IPU_CONF_CSI0_EN, ipu_clk);
+    if (ret) {
+        unit = "csi0";
+        goto err_csi_0;
+    }
+
+    ret = ipu_csi_init(ipu, dev, 1, ipu_base + devtype->csi1_ofs,
+               IPU_CONF_CSI1_EN, ipu_clk);
+    if (ret) {
+        unit = "csi1";
+        goto err_csi_1;
+    }
+
     ret = ipu_di_init(ipu, dev, 0, ipu_base + devtype->disp0_ofs,
             IPU_CONF_DI0_EN, ipu_clk);
     if (ret) {
@@ -562,6 +572,10 @@ err_dc:
 err_di_1:
     ipu_di_exit(ipu, 0);
 err_di_0:
+    ipu_csi_exit(ipu, 1);
+err_csi_1:
+    ipu_csi_exit(ipu, 0);
+err_csi_0:
     ipu_cpmem_exit(ipu);
 err_cpmem:
     dev_err(&pdev->dev, "init %s failed with %d\n", unit, ret);
@@ -640,6 +654,8 @@ static void ipu_submodules_exit(struct ipu_soc *ipu)
     ipu_dc_exit(ipu);
     ipu_di_exit(ipu, 1);
     ipu_di_exit(ipu, 0);
+    ipu_csi_exit(ipu, 1);
+    ipu_csi_exit(ipu, 0);
     ipu_cpmem_exit(ipu);
 }
 
@@ -859,6 +875,10 @@ static int ipu_probe(struct platform_device *pdev)
             ipu_base + devtype->cm_ofs + IPU_CM_IDMAC_REG_OFS);
     dev_dbg(&pdev->dev, "cpmem:    0x%08lx\n",
             ipu_base + devtype->cpmem_ofs);
+    dev_dbg(&pdev->dev, "csi0:    0x%08lx\n",
+            ipu_base + devtype->csi0_ofs);
+    dev_dbg(&pdev->dev, "csi1:    0x%08lx\n",
+            ipu_base + devtype->csi1_ofs);
     dev_dbg(&pdev->dev, "disp0:    0x%08lx\n",
             ipu_base + devtype->disp0_ofs);
     dev_dbg(&pdev->dev, "disp1:    0x%08lx\n",
diff --git a/drivers/gpu/ipu-v3/ipu-csi.c b/drivers/gpu/ipu-v3/ipu-csi.c
new file mode 100644
index 0000000..6d640e9
--- /dev/null
+++ b/drivers/gpu/ipu-v3/ipu-csi.c
@@ -0,0 +1,768 @@
+/*
+ * Copyright (C) 2012-2014 Mentor Graphics Inc.
+ * Copyright (C) 2005-2009 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * 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.
+ */
+#include <linux/export.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/videodev2.h>
+#include <uapi/linux/v4l2-mediabus.h>
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+
+#include "ipu-prv.h"
+
+struct ipu_csi {
+    void __iomem *base;
+    int id;
+    u32 module;
+    struct clk *clk_ipu;    /* IPU bus clock */
+    spinlock_t lock;
+    bool inuse;
+    struct ipu_soc *ipu;
+};
+
+/* CSI Register Offsets */
+#define CSI_SENS_CONF           0x0000
+#define CSI_SENS_FRM_SIZE       0x0004
+#define CSI_ACT_FRM_SIZE        0x0008
+#define CSI_OUT_FRM_CTRL        0x000C
+#define CSI_TST_CTRL            0x0010
+#define CSI_CCIR_CODE_1         0x0014
+#define CSI_CCIR_CODE_2         0x0018
+#define CSI_CCIR_CODE_3         0x001C
+#define CSI_MIPI_DI             0x0020
+#define CSI_SKIP                0x0024
+#define CSI_CPD_CTRL            0x0028
+#define CSI_CPD_RC(n)           (0x002C + ((n)*4))
+#define CSI_CPD_RS(n)           (0x004C + ((n)*4))
+#define CSI_CPD_GRC(n)          (0x005C + ((n)*4))
+#define CSI_CPD_GRS(n)          (0x007C + ((n)*4))
+#define CSI_CPD_GBC(n)          (0x008C + ((n)*4))
+#define CSI_CPD_GBS(n)          (0x00AC + ((n)*4))
+#define CSI_CPD_BC(n)           (0x00BC + ((n)*4))
+#define CSI_CPD_BS(n)           (0x00DC + ((n)*4))
+#define CSI_CPD_OFFSET1         0x00EC
+#define CSI_CPD_OFFSET2         0x00F0
+
+/* CSI Register Fields */
+#define CSI_SENS_CONF_DATA_FMT_SHIFT       8
+#define CSI_SENS_CONF_DATA_FMT_MASK        0x00000700
+#define CSI_SENS_CONF_DATA_FMT_RGB_YUV444  0L
+#define CSI_SENS_CONF_DATA_FMT_YUV422_YUYV 1L
+#define CSI_SENS_CONF_DATA_FMT_YUV422_UYVY 2L
+#define CSI_SENS_CONF_DATA_FMT_BAYER       3L
+#define CSI_SENS_CONF_DATA_FMT_RGB565      4L
+#define CSI_SENS_CONF_DATA_FMT_RGB555      5L
+#define CSI_SENS_CONF_DATA_FMT_RGB444      6L
+#define CSI_SENS_CONF_DATA_FMT_JPEG        7L
+
+#define CSI_SENS_CONF_VSYNC_POL_SHIFT      0
+#define CSI_SENS_CONF_HSYNC_POL_SHIFT      1
+#define CSI_SENS_CONF_DATA_POL_SHIFT       2
+#define CSI_SENS_CONF_PIX_CLK_POL_SHIFT    3
+#define CSI_SENS_CONF_SENS_PRTCL_MASK      0x00000070L
+#define CSI_SENS_CONF_SENS_PRTCL_SHIFT     4
+#define CSI_SENS_CONF_PACK_TIGHT_SHIFT     7
+#define CSI_SENS_CONF_DATA_WIDTH_SHIFT     11
+#define CSI_SENS_CONF_EXT_VSYNC_SHIFT      15
+#define CSI_SENS_CONF_DIVRATIO_SHIFT       16
+
+#define CSI_SENS_CONF_DIVRATIO_MASK        0x00FF0000L
+#define CSI_SENS_CONF_DATA_DEST_SHIFT      24
+#define CSI_SENS_CONF_DATA_DEST_MASK       0x07000000L
+#define CSI_SENS_CONF_JPEG8_EN_SHIFT       27
+#define CSI_SENS_CONF_JPEG_EN_SHIFT        28
+#define CSI_SENS_CONF_FORCE_EOF_SHIFT      29
+#define CSI_SENS_CONF_DATA_EN_POL_SHIFT    31
+
+#define CSI_DATA_DEST_IC                   2L
+#define CSI_DATA_DEST_IDMAC                4L
+
+#define CSI_CCIR_ERR_DET_EN                0x01000000L
+#define CSI_HORI_DOWNSIZE_EN               0x80000000L
+#define CSI_VERT_DOWNSIZE_EN               0x40000000L
+#define CSI_TEST_GEN_MODE_EN               0x01000000L
+
+#define CSI_HSC_MASK                       0x1FFF0000
+#define CSI_HSC_SHIFT                      16
+#define CSI_VSC_MASK                       0x00000FFF
+#define CSI_VSC_SHIFT                      0
+
+#define CSI_TEST_GEN_R_MASK                0x000000FFL
+#define CSI_TEST_GEN_R_SHIFT               0
+#define CSI_TEST_GEN_G_MASK                0x0000FF00L
+#define CSI_TEST_GEN_G_SHIFT               8
+#define CSI_TEST_GEN_B_MASK                0x00FF0000L
+#define CSI_TEST_GEN_B_SHIFT               16
+
+#define CSI_MAX_RATIO_SKIP_SMFC_MASK       0x00000007L
+#define CSI_MAX_RATIO_SKIP_SMFC_SHIFT      0
+#define CSI_SKIP_SMFC_MASK                 0x000000F8L
+#define CSI_SKIP_SMFC_SHIFT                3
+#define CSI_ID_2_SKIP_MASK                 0x00000300L
+#define CSI_ID_2_SKIP_SHIFT                8
+
+#define CSI_COLOR_FIRST_ROW_MASK           0x00000002L
+#define CSI_COLOR_FIRST_COMP_MASK          0x00000001L
+
+/* MIPI CSI-2 data types */
+#define MIPI_DT_YUV420        0x18 /* YYY.../UYVY.... */
+#define MIPI_DT_YUV420_LEGACY    0x1a /* UYY.../VYY...   */
+#define MIPI_DT_YUV422        0x1e /* UYVY...        */
+#define MIPI_DT_RGB444        0x20
+#define MIPI_DT_RGB555        0x21
+#define MIPI_DT_RGB565        0x22
+#define MIPI_DT_RGB666        0x23
+#define MIPI_DT_RGB888        0x24
+#define MIPI_DT_RAW6        0x28
+#define MIPI_DT_RAW7        0x29
+#define MIPI_DT_RAW8        0x2a
+#define MIPI_DT_RAW10        0x2b
+#define MIPI_DT_RAW12        0x2c
+#define MIPI_DT_RAW14        0x2d
+
+/*
+ * Bitfield of CSI bus signal polarities and modes.
+ */
+struct ipu_csi_bus_config {
+    unsigned data_width:4;
+    unsigned clk_mode:3;
+    unsigned ext_vsync:1;
+    unsigned vsync_pol:1;
+    unsigned hsync_pol:1;
+    unsigned pixclk_pol:1;
+    unsigned data_pol:1;
+    unsigned sens_clksrc:1;
+    unsigned pack_tight:1;
+    unsigned force_eof:1;
+    unsigned data_en_pol:1;
+
+    unsigned data_fmt;
+    unsigned mipi_dt;
+};
+
+/*
+ * Enumeration of CSI data bus widths.
+ */
+enum ipu_csi_data_width {
+    IPU_CSI_DATA_WIDTH_4   = 0,
+    IPU_CSI_DATA_WIDTH_8   = 1,
+    IPU_CSI_DATA_WIDTH_10  = 3,
+    IPU_CSI_DATA_WIDTH_12  = 5,
+    IPU_CSI_DATA_WIDTH_16  = 9,
+};
+
+/*
+ * Enumeration of CSI clock modes.
+ */
+enum ipu_csi_clk_mode {
+    IPU_CSI_CLK_MODE_GATED_CLK,
+    IPU_CSI_CLK_MODE_NONGATED_CLK,
+    IPU_CSI_CLK_MODE_CCIR656_PROGRESSIVE,
+    IPU_CSI_CLK_MODE_CCIR656_INTERLACED,
+    IPU_CSI_CLK_MODE_CCIR1120_PROGRESSIVE_DDR,
+    IPU_CSI_CLK_MODE_CCIR1120_PROGRESSIVE_SDR,
+    IPU_CSI_CLK_MODE_CCIR1120_INTERLACED_DDR,
+    IPU_CSI_CLK_MODE_CCIR1120_INTERLACED_SDR,
+};
+
+static inline u32 ipu_csi_read(struct ipu_csi *csi, unsigned offset)
+{
+    return readl(csi->base + offset);
+}
+
+static inline void ipu_csi_write(struct ipu_csi *csi, u32 value,
+                 unsigned offset)
+{
+    writel(value, csi->base + offset);
+}
+
+static inline void ipu_csi_set_horizontal_downsize(struct ipu_csi *csi,
+                           bool enable)
+{
+    u32 temp;
+
+    temp = ipu_csi_read(csi, CSI_OUT_FRM_CTRL);
+    if (enable)
+        temp |= CSI_HORI_DOWNSIZE_EN;
+    else
+        temp &= ~CSI_HORI_DOWNSIZE_EN;
+    ipu_csi_write(csi, temp, CSI_OUT_FRM_CTRL);
+}
+
+static inline void ipu_csi_set_vertical_downsize(struct ipu_csi *csi,
+                         bool enable)
+{
+    u32 temp;
+
+    temp = ipu_csi_read(csi, CSI_OUT_FRM_CTRL);
+    if (enable)
+        temp |= CSI_VERT_DOWNSIZE_EN;
+    else
+        temp &= ~CSI_VERT_DOWNSIZE_EN;
+    ipu_csi_write(csi, temp, CSI_OUT_FRM_CTRL);
+}
+
+/*
+ * Set mclk division ratio for generating test mode mclk. Only used
+ * for test generator.
+ */
+static int ipu_csi_set_testgen_mclk(struct ipu_csi *csi, u32 pixel_clk,
+                    u32 ipu_clk)
+{
+    u32 temp;
+    u32 div_ratio;
+
+    div_ratio = (ipu_clk / pixel_clk) - 1;
+
+    if (div_ratio > 0xFF || div_ratio < 0) {
+        dev_err(csi->ipu->dev,
+            "value of pixel_clk extends normal range\n");
+        return -EINVAL;
+    }
+
+    temp = ipu_csi_read(csi, CSI_SENS_CONF);
+    temp &= ~CSI_SENS_CONF_DIVRATIO_MASK;
+    ipu_csi_write(csi, temp | (div_ratio << CSI_SENS_CONF_DIVRATIO_SHIFT),
+              CSI_SENS_CONF);
+
+    return 0;
+}
+
+/*
+ * Find the CSI data format and data width for the given V4L2 media
+ * bus pixel format code.
+ */
+static int mbus_code_to_bus_cfg(struct ipu_csi_bus_config *cfg, u32 mbus_code)
+{
+    switch (mbus_code) {
+    case V4L2_MBUS_FMT_BGR565_2X8_BE:
+    case V4L2_MBUS_FMT_BGR565_2X8_LE:
+    case V4L2_MBUS_FMT_RGB565_2X8_BE:
+    case V4L2_MBUS_FMT_RGB565_2X8_LE:
+        cfg->data_fmt = CSI_SENS_CONF_DATA_FMT_RGB565;
+        cfg->mipi_dt = MIPI_DT_RGB565;
+        cfg->data_width = IPU_CSI_DATA_WIDTH_8;
+        break;
+    case V4L2_MBUS_FMT_RGB444_2X8_PADHI_BE:
+    case V4L2_MBUS_FMT_RGB444_2X8_PADHI_LE:
+        cfg->data_fmt = CSI_SENS_CONF_DATA_FMT_RGB444;
+        cfg->mipi_dt = MIPI_DT_RGB444;
+        cfg->data_width = IPU_CSI_DATA_WIDTH_8;
+        break;
+    case V4L2_MBUS_FMT_RGB555_2X8_PADHI_BE:
+    case V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE:
+        cfg->data_fmt = CSI_SENS_CONF_DATA_FMT_RGB555;
+        cfg->mipi_dt = MIPI_DT_RGB555;
+        cfg->data_width = IPU_CSI_DATA_WIDTH_8;
+        break;
+    case V4L2_MBUS_FMT_UYVY8_2X8:
+        cfg->data_fmt = CSI_SENS_CONF_DATA_FMT_YUV422_UYVY;
+        cfg->mipi_dt = MIPI_DT_YUV422;
+        cfg->data_width = IPU_CSI_DATA_WIDTH_8;
+        break;
+    case V4L2_MBUS_FMT_YUYV8_2X8:
+        cfg->data_fmt = CSI_SENS_CONF_DATA_FMT_YUV422_YUYV;
+        cfg->mipi_dt = MIPI_DT_YUV422;
+        cfg->data_width = IPU_CSI_DATA_WIDTH_8;
+        break;
+    case V4L2_MBUS_FMT_UYVY8_1X16:
+        cfg->data_fmt = CSI_SENS_CONF_DATA_FMT_YUV422_UYVY;
+        cfg->mipi_dt = MIPI_DT_YUV422;
+        cfg->data_width = IPU_CSI_DATA_WIDTH_16;
+        break;
+    case V4L2_MBUS_FMT_YUYV8_1X16:
+        cfg->data_fmt = CSI_SENS_CONF_DATA_FMT_YUV422_YUYV;
+        cfg->mipi_dt = MIPI_DT_YUV422;
+        cfg->data_width = IPU_CSI_DATA_WIDTH_16;
+        break;
+    case V4L2_MBUS_FMT_SBGGR8_1X8:
+    case V4L2_MBUS_FMT_SGBRG8_1X8:
+    case V4L2_MBUS_FMT_SGRBG8_1X8:
+    case V4L2_MBUS_FMT_SRGGB8_1X8:
+        cfg->data_fmt = CSI_SENS_CONF_DATA_FMT_BAYER;
+        cfg->mipi_dt = MIPI_DT_RAW8;
+        cfg->data_width = IPU_CSI_DATA_WIDTH_8;
+        break;
+    case V4L2_MBUS_FMT_SBGGR10_DPCM8_1X8:
+    case V4L2_MBUS_FMT_SGBRG10_DPCM8_1X8:
+    case V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8:
+    case V4L2_MBUS_FMT_SRGGB10_DPCM8_1X8:
+    case V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_BE:
+    case V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE:
+    case V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_BE:
+    case V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_LE:
+        cfg->data_fmt = CSI_SENS_CONF_DATA_FMT_BAYER;
+        cfg->mipi_dt = MIPI_DT_RAW10;
+        cfg->data_width = IPU_CSI_DATA_WIDTH_8;
+        break;
+    case V4L2_MBUS_FMT_SBGGR10_1X10:
+    case V4L2_MBUS_FMT_SGBRG10_1X10:
+    case V4L2_MBUS_FMT_SGRBG10_1X10:
+    case V4L2_MBUS_FMT_SRGGB10_1X10:
+        cfg->data_fmt = CSI_SENS_CONF_DATA_FMT_BAYER;
+        cfg->mipi_dt = MIPI_DT_RAW10;
+        cfg->data_width = IPU_CSI_DATA_WIDTH_10;
+        break;
+    case V4L2_MBUS_FMT_SBGGR12_1X12:
+    case V4L2_MBUS_FMT_SGBRG12_1X12:
+    case V4L2_MBUS_FMT_SGRBG12_1X12:
+    case V4L2_MBUS_FMT_SRGGB12_1X12:
+        cfg->data_fmt = CSI_SENS_CONF_DATA_FMT_BAYER;
+        cfg->mipi_dt = MIPI_DT_RAW12;
+        cfg->data_width = IPU_CSI_DATA_WIDTH_12;
+        break;
+    case V4L2_MBUS_FMT_JPEG_1X8:
+        /* TODO */
+        cfg->data_fmt = CSI_SENS_CONF_DATA_FMT_JPEG;
+        cfg->mipi_dt = MIPI_DT_RAW8;
+        cfg->data_width = IPU_CSI_DATA_WIDTH_8;
+        break;
+    default:
+        return -EINVAL;
+    }
+
+    return 0;
+}
+
+/*
+ * Fill a CSI bus config struct from mbus_config and mbus_framefmt.
+ */
+static void fill_csi_bus_cfg(struct ipu_csi_bus_config *csicfg,
+                 struct v4l2_mbus_config *mbus_cfg,
+                 struct v4l2_mbus_framefmt *mbus_fmt)
+{
+    memset(csicfg, 0, sizeof(*csicfg));
+
+    mbus_code_to_bus_cfg(csicfg, mbus_fmt->code);
+
+    switch (mbus_cfg->type) {
+    case V4L2_MBUS_PARALLEL:
+        csicfg->ext_vsync = 1;
+        csicfg->vsync_pol = (mbus_cfg->flags &
+                     V4L2_MBUS_VSYNC_ACTIVE_LOW) ? 1 : 0;
+        csicfg->hsync_pol = (mbus_cfg->flags &
+                     V4L2_MBUS_HSYNC_ACTIVE_LOW) ? 1 : 0;
+        csicfg->pixclk_pol = (mbus_cfg->flags &
+                      V4L2_MBUS_PCLK_SAMPLE_FALLING) ? 1 : 0;
+        csicfg->clk_mode = IPU_CSI_CLK_MODE_GATED_CLK;
+        break;
+    case V4L2_MBUS_BT656:
+        csicfg->ext_vsync = 0;
+        if (V4L2_FIELD_HAS_BOTH(mbus_fmt->field))
+            csicfg->clk_mode = IPU_CSI_CLK_MODE_CCIR656_INTERLACED;
+        else
+            csicfg->clk_mode = IPU_CSI_CLK_MODE_CCIR656_PROGRESSIVE;
+        break;
+    case V4L2_MBUS_CSI2:
+        /*
+         * MIPI CSI-2 requires non gated clock mode, all other
+         * parameters are not applicable for MIPI CSI-2 bus.
+         */
+        csicfg->clk_mode = IPU_CSI_CLK_MODE_NONGATED_CLK;
+        break;
+    default:
+        /* will never get here, keep compiler quiet */
+        break;
+    }
+}
+
+int ipu_csi_init_interface(struct ipu_csi *csi,
+               struct v4l2_mbus_config *mbus_cfg,
+               struct v4l2_mbus_framefmt *mbus_fmt)
+{
+    struct ipu_csi_bus_config cfg;
+    unsigned long flags;
+    u32 data = 0;
+
+    fill_csi_bus_cfg(&cfg, mbus_cfg, mbus_fmt);
+
+    /* Set the CSI_SENS_CONF register remaining fields */
+    data |= cfg.data_width << CSI_SENS_CONF_DATA_WIDTH_SHIFT |
+        cfg.data_fmt << CSI_SENS_CONF_DATA_FMT_SHIFT |
+        cfg.data_pol << CSI_SENS_CONF_DATA_POL_SHIFT |
+        cfg.vsync_pol << CSI_SENS_CONF_VSYNC_POL_SHIFT |
+        cfg.hsync_pol << CSI_SENS_CONF_HSYNC_POL_SHIFT |
+        cfg.pixclk_pol << CSI_SENS_CONF_PIX_CLK_POL_SHIFT |
+        cfg.ext_vsync << CSI_SENS_CONF_EXT_VSYNC_SHIFT |
+        cfg.clk_mode << CSI_SENS_CONF_SENS_PRTCL_SHIFT |
+        cfg.pack_tight << CSI_SENS_CONF_PACK_TIGHT_SHIFT |
+        cfg.force_eof << CSI_SENS_CONF_FORCE_EOF_SHIFT |
+        cfg.data_en_pol << CSI_SENS_CONF_DATA_EN_POL_SHIFT;
+
+    spin_lock_irqsave(&csi->lock, flags);
+
+    ipu_csi_write(csi, data, CSI_SENS_CONF);
+
+    /* Setup sensor frame size */
+    ipu_csi_write(csi,
+              (mbus_fmt->width - 1) | ((mbus_fmt->height - 1) << 16),
+              CSI_SENS_FRM_SIZE);
+
+    /* Set CCIR registers */
+
+    switch (cfg.clk_mode) {
+    case IPU_CSI_CLK_MODE_CCIR656_PROGRESSIVE:
+        ipu_csi_write(csi, 0x40030, CSI_CCIR_CODE_1);
+        ipu_csi_write(csi, 0xFF0000, CSI_CCIR_CODE_3);
+        break;
+    case IPU_CSI_CLK_MODE_CCIR656_INTERLACED:
+        if (mbus_fmt->width == 720 && mbus_fmt->height == 576) {
+            /*
+             * PAL case
+             *
+             * Field0BlankEnd = 0x6, Field0BlankStart = 0x2,
+             * Field0ActiveEnd = 0x4, Field0ActiveStart = 0
+             * Field1BlankEnd = 0x7, Field1BlankStart = 0x3,
+             * Field1ActiveEnd = 0x5, Field1ActiveStart = 0x1
+             */
+            ipu_csi_write(csi, 0x40596 | CSI_CCIR_ERR_DET_EN,
+                      CSI_CCIR_CODE_1);
+            ipu_csi_write(csi, 0xD07DF, CSI_CCIR_CODE_2);
+            ipu_csi_write(csi, 0xFF0000, CSI_CCIR_CODE_3);
+
+        } else if (mbus_fmt->width == 720 && mbus_fmt->height == 480) {
+            /*
+             * NTSC case
+             *
+             * Field0BlankEnd = 0x7, Field0BlankStart = 0x3,
+             * Field0ActiveEnd = 0x5, Field0ActiveStart = 0x1
+             * Field1BlankEnd = 0x6, Field1BlankStart = 0x2,
+             * Field1ActiveEnd = 0x4, Field1ActiveStart = 0
+             */
+            ipu_csi_write(csi, 0xD07DF | CSI_CCIR_ERR_DET_EN,
+                      CSI_CCIR_CODE_1);
+            ipu_csi_write(csi, 0x40596, CSI_CCIR_CODE_2);
+            ipu_csi_write(csi, 0xFF0000, CSI_CCIR_CODE_3);
+        } else {
+            dev_err(csi->ipu->dev,
+                "Unsupported CCIR656 interlaced video mode\n");
+            spin_unlock_irqrestore(&csi->lock, flags);
+            return -EINVAL;
+        }
+        break;
+    case IPU_CSI_CLK_MODE_CCIR1120_PROGRESSIVE_DDR:
+    case IPU_CSI_CLK_MODE_CCIR1120_PROGRESSIVE_SDR:
+    case IPU_CSI_CLK_MODE_CCIR1120_INTERLACED_DDR:
+    case IPU_CSI_CLK_MODE_CCIR1120_INTERLACED_SDR:
+        ipu_csi_write(csi, 0x40030 | CSI_CCIR_ERR_DET_EN,
+                   CSI_CCIR_CODE_1);
+        ipu_csi_write(csi, 0xFF0000, CSI_CCIR_CODE_3);
+        break;
+    case IPU_CSI_CLK_MODE_GATED_CLK:
+    case IPU_CSI_CLK_MODE_NONGATED_CLK:
+        ipu_csi_write(csi, 0, CSI_CCIR_CODE_1);
+        break;
+    }
+
+    dev_dbg(csi->ipu->dev, "CSI_SENS_CONF = 0x%08X\n",
+        ipu_csi_read(csi, CSI_SENS_CONF));
+    dev_dbg(csi->ipu->dev, "CSI_ACT_FRM_SIZE = 0x%08X\n",
+        ipu_csi_read(csi, CSI_ACT_FRM_SIZE));
+
+    spin_unlock_irqrestore(&csi->lock, flags);
+
+    return 0;
+}
+EXPORT_SYMBOL_GPL(ipu_csi_init_interface);
+
+bool ipu_csi_is_interlaced(struct ipu_csi *csi)
+{
+    unsigned long flags;
+    u32 sensor_protocol;
+
+    spin_lock_irqsave(&csi->lock, flags);
+    sensor_protocol =
+        (ipu_csi_read(csi, CSI_SENS_CONF) &
+         CSI_SENS_CONF_SENS_PRTCL_MASK) >>
+        CSI_SENS_CONF_SENS_PRTCL_SHIFT;
+    spin_unlock_irqrestore(&csi->lock, flags);
+
+    switch (sensor_protocol) {
+    case IPU_CSI_CLK_MODE_GATED_CLK:
+    case IPU_CSI_CLK_MODE_NONGATED_CLK:
+    case IPU_CSI_CLK_MODE_CCIR656_PROGRESSIVE:
+    case IPU_CSI_CLK_MODE_CCIR1120_PROGRESSIVE_DDR:
+    case IPU_CSI_CLK_MODE_CCIR1120_PROGRESSIVE_SDR:
+        return false;
+    case IPU_CSI_CLK_MODE_CCIR656_INTERLACED:
+    case IPU_CSI_CLK_MODE_CCIR1120_INTERLACED_DDR:
+    case IPU_CSI_CLK_MODE_CCIR1120_INTERLACED_SDR:
+        return true;
+    default:
+        dev_err(csi->ipu->dev,
+            "CSI %d sensor protocol unsupported\n", csi->id);
+        return false;
+    }
+}
+EXPORT_SYMBOL_GPL(ipu_csi_is_interlaced);
+
+void ipu_csi_get_window(struct ipu_csi *csi, struct v4l2_rect *w)
+{
+    unsigned long flags;
+    u32 reg;
+
+    spin_lock_irqsave(&csi->lock, flags);
+
+    reg = ipu_csi_read(csi, CSI_ACT_FRM_SIZE);
+    w->width = (reg & 0xFFFF) + 1;
+    w->height = (reg >> 16 & 0xFFFF) + 1;
+
+    reg = ipu_csi_read(csi, CSI_OUT_FRM_CTRL);
+    w->left = (reg & CSI_HSC_MASK) >> CSI_HSC_SHIFT;
+    w->top = (reg & CSI_VSC_MASK) >> CSI_VSC_SHIFT;
+
+    spin_unlock_irqrestore(&csi->lock, flags);
+}
+EXPORT_SYMBOL_GPL(ipu_csi_get_window);
+
+void ipu_csi_set_window(struct ipu_csi *csi, struct v4l2_rect *w)
+{
+    unsigned long flags;
+    u32 reg;
+
+    spin_lock_irqsave(&csi->lock, flags);
+
+    ipu_csi_write(csi, (w->width - 1) | ((w->height - 1) << 16),
+              CSI_ACT_FRM_SIZE);
+
+    reg = ipu_csi_read(csi, CSI_OUT_FRM_CTRL);
+    reg &= ~(CSI_HSC_MASK | CSI_VSC_MASK);
+    reg |= ((w->top << CSI_VSC_SHIFT) | (w->left << CSI_HSC_SHIFT));
+    ipu_csi_write(csi, reg, CSI_OUT_FRM_CTRL);
+
+    spin_unlock_irqrestore(&csi->lock, flags);
+}
+EXPORT_SYMBOL_GPL(ipu_csi_set_window);
+
+void ipu_csi_set_test_generator(struct ipu_csi *csi, bool active,
+                u32 r_value, u32 g_value, u32 b_value,
+                u32 pix_clk)
+{
+    unsigned long flags;
+    u32 ipu_clk = clk_get_rate(csi->clk_ipu);
+    u32 temp;
+
+    spin_lock_irqsave(&csi->lock, flags);
+
+    temp = ipu_csi_read(csi, CSI_TST_CTRL);
+
+    if (active == false) {
+        temp &= ~CSI_TEST_GEN_MODE_EN;
+        ipu_csi_write(csi, temp, CSI_TST_CTRL);
+    } else {
+        /* Set sensb_mclk div_ratio*/
+        ipu_csi_set_testgen_mclk(csi, pix_clk, ipu_clk);
+
+        temp &= ~(CSI_TEST_GEN_R_MASK | CSI_TEST_GEN_G_MASK |
+              CSI_TEST_GEN_B_MASK);
+        temp |= CSI_TEST_GEN_MODE_EN;
+        temp |= (r_value << CSI_TEST_GEN_R_SHIFT) |
+            (g_value << CSI_TEST_GEN_G_SHIFT) |
+            (b_value << CSI_TEST_GEN_B_SHIFT);
+        ipu_csi_write(csi, temp, CSI_TST_CTRL);
+    }
+
+    spin_unlock_irqrestore(&csi->lock, flags);
+}
+EXPORT_SYMBOL_GPL(ipu_csi_set_test_generator);
+
+int ipu_csi_set_mipi_datatype(struct ipu_csi *csi, u32 vc,
+                  struct v4l2_mbus_framefmt *mbus_fmt)
+{
+    struct ipu_csi_bus_config cfg;
+    unsigned long flags;
+    u32 temp;
+
+    if (vc > 3)
+        return -EINVAL;
+
+    mbus_code_to_bus_cfg(&cfg, mbus_fmt->code);
+
+    spin_lock_irqsave(&csi->lock, flags);
+
+    temp = ipu_csi_read(csi, CSI_MIPI_DI);
+    temp &= ~(0xff << (vc * 8));
+    temp |= (cfg.mipi_dt << (vc * 8));
+    ipu_csi_write(csi, temp, CSI_MIPI_DI);
+
+    spin_unlock_irqrestore(&csi->lock, flags);
+
+    return 0;
+}
+EXPORT_SYMBOL_GPL(ipu_csi_set_mipi_datatype);
+
+int ipu_csi_set_skip_smfc(struct ipu_csi *csi, u32 skip,
+              u32 max_ratio, u32 id)
+{
+    unsigned long flags;
+    u32 temp;
+
+    if (max_ratio > 5 || id > 3)
+        return -EINVAL;
+
+    spin_lock_irqsave(&csi->lock, flags);
+
+    temp = ipu_csi_read(csi, CSI_SKIP);
+    temp &= ~(CSI_MAX_RATIO_SKIP_SMFC_MASK | CSI_ID_2_SKIP_MASK |
+          CSI_SKIP_SMFC_MASK);
+    temp |= (max_ratio << CSI_MAX_RATIO_SKIP_SMFC_SHIFT) |
+        (id << CSI_ID_2_SKIP_SHIFT) |
+        (skip << CSI_SKIP_SMFC_SHIFT);
+    ipu_csi_write(csi, temp, CSI_SKIP);
+
+    spin_unlock_irqrestore(&csi->lock, flags);
+
+    return 0;
+}
+EXPORT_SYMBOL_GPL(ipu_csi_set_skip_smfc);
+
+int ipu_csi_set_dest(struct ipu_csi *csi, enum ipu_csi_dest csi_dest)
+{
+    unsigned long flags;
+    u32 csi_sens_conf, dest;
+
+    if (csi_dest == IPU_CSI_DEST_IDMAC)
+        dest = CSI_DATA_DEST_IDMAC;
+    else
+        dest = CSI_DATA_DEST_IC; /* IC or VDIC */
+
+
+    spin_lock_irqsave(&csi->lock, flags);
+
+    csi_sens_conf = ipu_csi_read(csi, CSI_SENS_CONF);
+    csi_sens_conf &= ~CSI_SENS_CONF_DATA_DEST_MASK;
+    csi_sens_conf |= (dest << CSI_SENS_CONF_DATA_DEST_SHIFT);
+    ipu_csi_write(csi, csi_sens_conf, CSI_SENS_CONF);
+
+    spin_unlock_irqrestore(&csi->lock, flags);
+
+    return 0;
+}
+EXPORT_SYMBOL_GPL(ipu_csi_set_dest);
+
+int ipu_csi_enable(struct ipu_csi *csi)
+{
+    ipu_module_enable(csi->ipu, csi->module);
+
+    return 0;
+}
+EXPORT_SYMBOL_GPL(ipu_csi_enable);
+
+int ipu_csi_disable(struct ipu_csi *csi)
+{
+    ipu_module_disable(csi->ipu, csi->module);
+
+    return 0;
+}
+EXPORT_SYMBOL_GPL(ipu_csi_disable);
+
+struct ipu_csi *ipu_csi_get(struct ipu_soc *ipu, int id)
+{
+    unsigned long flags;
+    struct ipu_csi *csi, *ret;
+
+    if (id > 1)
+        return ERR_PTR(-EINVAL);
+
+    csi = ipu->csi_priv[id];
+    ret = csi;
+
+    spin_lock_irqsave(&csi->lock, flags);
+
+    if (csi->inuse) {
+        ret = ERR_PTR(-EBUSY);
+        goto unlock;
+    }
+
+    csi->inuse = true;
+unlock:
+    spin_unlock_irqrestore(&csi->lock, flags);
+    return ret;
+}
+EXPORT_SYMBOL_GPL(ipu_csi_get);
+
+void ipu_csi_put(struct ipu_csi *csi)
+{
+    unsigned long flags;
+
+    spin_lock_irqsave(&csi->lock, flags);
+    csi->inuse = false;
+    spin_unlock_irqrestore(&csi->lock, flags);
+}
+EXPORT_SYMBOL_GPL(ipu_csi_put);
+
+int ipu_csi_init(struct ipu_soc *ipu, struct device *dev, int id,
+         unsigned long base, u32 module, struct clk *clk_ipu)
+{
+    struct ipu_csi *csi;
+
+    if (id > 1)
+        return -ENODEV;
+
+    csi = devm_kzalloc(dev, sizeof(*csi), GFP_KERNEL);
+    if (!csi)
+        return -ENOMEM;
+
+    ipu->csi_priv[id] = csi;
+
+    spin_lock_init(&csi->lock);
+    csi->module = module;
+    csi->id = id;
+    csi->clk_ipu = clk_ipu;
+    csi->base = devm_ioremap(dev, base, PAGE_SIZE);
+    if (!csi->base)
+        return -ENOMEM;
+
+    dev_dbg(dev, "CSI%d base: 0x%08lx remapped to %p\n",
+        id, base, csi->base);
+    csi->ipu = ipu;
+
+    return 0;
+}
+
+void ipu_csi_exit(struct ipu_soc *ipu, int id)
+{
+}
+
+void ipu_csi_dump(struct ipu_csi *csi)
+{
+    dev_dbg(csi->ipu->dev, "CSI_SENS_CONF:     %08x\n",
+        ipu_csi_read(csi, CSI_SENS_CONF));
+    dev_dbg(csi->ipu->dev, "CSI_SENS_FRM_SIZE: %08x\n",
+        ipu_csi_read(csi, CSI_SENS_FRM_SIZE));
+    dev_dbg(csi->ipu->dev, "CSI_ACT_FRM_SIZE:  %08x\n",
+        ipu_csi_read(csi, CSI_ACT_FRM_SIZE));
+    dev_dbg(csi->ipu->dev, "CSI_OUT_FRM_CTRL:  %08x\n",
+        ipu_csi_read(csi, CSI_OUT_FRM_CTRL));
+    dev_dbg(csi->ipu->dev, "CSI_TST_CTRL:      %08x\n",
+        ipu_csi_read(csi, CSI_TST_CTRL));
+    dev_dbg(csi->ipu->dev, "CSI_CCIR_CODE_1:   %08x\n",
+        ipu_csi_read(csi, CSI_CCIR_CODE_1));
+    dev_dbg(csi->ipu->dev, "CSI_CCIR_CODE_2:   %08x\n",
+        ipu_csi_read(csi, CSI_CCIR_CODE_2));
+    dev_dbg(csi->ipu->dev, "CSI_CCIR_CODE_3:   %08x\n",
+        ipu_csi_read(csi, CSI_CCIR_CODE_3));
+    dev_dbg(csi->ipu->dev, "CSI_MIPI_DI:       %08x\n",
+        ipu_csi_read(csi, CSI_MIPI_DI));
+    dev_dbg(csi->ipu->dev, "CSI_SKIP:          %08x\n",
+        ipu_csi_read(csi, CSI_SKIP));
+}
+EXPORT_SYMBOL_GPL(ipu_csi_dump);
diff --git a/drivers/gpu/ipu-v3/ipu-prv.h b/drivers/gpu/ipu-v3/ipu-prv.h
index 1a5c55c..9b274f1 100644
--- a/drivers/gpu/ipu-v3/ipu-prv.h
+++ b/drivers/gpu/ipu-v3/ipu-prv.h
@@ -157,6 +157,7 @@ struct ipuv3_channel {
 };
 
 struct ipu_cpmem;
+struct ipu_csi;
 struct ipu_dc_priv;
 struct ipu_dmfc_priv;
 struct ipu_di;
@@ -189,6 +190,7 @@ struct ipu_soc {
     struct ipu_dp_priv    *dp_priv;
     struct ipu_dmfc_priv    *dmfc_priv;
     struct ipu_di        *di_priv[2];
+    struct ipu_csi        *csi_priv[2];
     struct ipu_smfc_priv    *smfc_priv;
 };
 
@@ -211,6 +213,10 @@ int ipu_module_disable(struct ipu_soc *ipu, u32 mask);
 bool ipu_idmac_channel_busy(struct ipu_soc *ipu, unsigned int chno);
 int ipu_wait_interrupt(struct ipu_soc *ipu, int irq, int ms);
 
+int ipu_csi_init(struct ipu_soc *ipu, struct device *dev, int id,
+         unsigned long base, u32 module, struct clk *clk_ipu);
+void ipu_csi_exit(struct ipu_soc *ipu, int id);
+
 int ipu_di_init(struct ipu_soc *ipu, struct device *dev, int id,
         unsigned long base, u32 module, struct clk *ipu_clk);
 void ipu_di_exit(struct ipu_soc *ipu, int id);
diff --git a/include/video/imx-ipu-v3.h b/include/video/imx-ipu-v3.h
index f80fe13..ebdab0d 100644
--- a/include/video/imx-ipu-v3.h
+++ b/include/video/imx-ipu-v3.h
@@ -16,6 +16,7 @@
 #include <linux/videodev2.h>
 #include <linux/bitmap.h>
 #include <linux/fb.h>
+#include <media/v4l2-mediabus.h>
 
 struct ipu_soc;
 
@@ -61,6 +62,15 @@ struct ipu_di_signal_cfg {
     u8 vsync_pin;
 };
 
+/*
+ * Enumeration of CSI destinations
+ */
+enum ipu_csi_dest {
+    IPU_CSI_DEST_IDMAC, /* to memory via SMFC */
+    IPU_CSI_DEST_IC,    /* to Image Converter */
+    IPU_CSI_DEST_VDIC,  /* to VDIC */
+};
+
 enum ipu_color_space {
     IPUV3_COLORSPACE_RGB,
     IPUV3_COLORSPACE_YUV,
@@ -211,8 +221,26 @@ int ipu_dp_set_global_alpha(struct ipu_dp *dp, bool enable, u8 alpha,
 /*
  * IPU CMOS Sensor Interface (csi) functions
  */
-int ipu_csi_enable(struct ipu_soc *ipu, int csi);
-int ipu_csi_disable(struct ipu_soc *ipu, int csi);
+struct ipu_csi;
+int ipu_csi_init_interface(struct ipu_csi *csi,
+               struct v4l2_mbus_config *mbus_cfg,
+               struct v4l2_mbus_framefmt *mbus_fmt);
+bool ipu_csi_is_interlaced(struct ipu_csi *csi);
+void ipu_csi_get_window(struct ipu_csi *csi, struct v4l2_rect *w);
+void ipu_csi_set_window(struct ipu_csi *csi, struct v4l2_rect *w);
+void ipu_csi_set_test_generator(struct ipu_csi *csi, bool active,
+                u32 r_value, u32 g_value, u32 b_value,
+                u32 pix_clk);
+int ipu_csi_set_mipi_datatype(struct ipu_csi *csi, u32 vc,
+                  struct v4l2_mbus_framefmt *mbus_fmt);
+int ipu_csi_set_skip_smfc(struct ipu_csi *csi, u32 skip,
+              u32 max_ratio, u32 id);
+int ipu_csi_set_dest(struct ipu_csi *csi, enum ipu_csi_dest csi_dest);
+int ipu_csi_enable(struct ipu_csi *csi);
+int ipu_csi_disable(struct ipu_csi *csi);
+struct ipu_csi *ipu_csi_get(struct ipu_soc *ipu, int id);
+void ipu_csi_put(struct ipu_csi *csi);
+void ipu_csi_dump(struct ipu_csi *csi);
 
 /*
  * IPU Sensor Multiple FIFO Controller (SMFC) functions
-- 
1.7.9.5

  reply	other threads:[~2014-08-19 17:52 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-08-18 13:39 [PATCH v2 00/26] IPUv3 prep for video capture Philipp Zabel
2014-08-18 13:40 ` [PATCH 01/26] gpu: ipu-v3: Add ipu-cpmem unit Philipp Zabel
2014-08-18 13:40 ` [PATCH 02/26] staging: imx-drm: Convert to new ipu_cpmem API Philipp Zabel
2014-08-18 13:40 ` [PATCH 03/26] gpu: ipu-v3: Add functions to set CSI/IC source muxes Philipp Zabel
2014-08-18 13:40 ` [PATCH 04/26] gpu: ipu-v3: Rename and add IDMAC channels Philipp Zabel
2014-08-18 13:40 ` [PATCH 05/26] gpu: ipu-v3: Add Camera Sensor Interface unit Philipp Zabel
2014-08-19 17:52   ` Steve Longerbeam [this message]
2014-08-18 13:40 ` [PATCH 06/26] gpu: ipu-v3: Add Image Converter unit Philipp Zabel
2014-08-18 13:40 ` [PATCH 07/26] gpu: ipu-v3: smfc: Move enable/disable to ipu-smfc.c Philipp Zabel
2014-08-18 13:40 ` [PATCH 08/26] gpu: ipu-v3: smfc: Convert to per-channel Philipp Zabel
2014-08-18 13:40 ` [PATCH 09/26] gpu: ipu-v3: smfc: Add ipu_smfc_set_watermark() Philipp Zabel
2014-08-18 13:40 ` [PATCH 10/26] gpu: ipu-v3: Add ipu_mbus_code_to_colorspace() Philipp Zabel
2014-08-18 13:40 ` [PATCH 11/26] gpu: ipu-v3: Add rotation mode conversion utilities Philipp Zabel
2014-08-18 13:40 ` [PATCH 12/26] gpu: ipu-v3: Add helper function checking if pixfmt is planar Philipp Zabel
2014-08-18 13:40 ` [PATCH 13/26] gpu: ipu-v3: Move IDMAC channel names to imx-ipu-v3.h Philipp Zabel
2014-08-18 13:40 ` [PATCH 14/26] gpu: ipu-v3: Add ipu_idmac_buffer_is_ready() Philipp Zabel
2014-08-18 13:40 ` [PATCH 15/26] gpu: ipu-v3: Add ipu_idmac_clear_buffer() Philipp Zabel
2014-08-18 13:40 ` [PATCH 16/26] gpu: ipu-v3: Add __ipu_idmac_reset_current_buffer() Philipp Zabel
2014-08-18 13:40 ` [PATCH 17/26] gpu: ipu-v3: Add ipu_stride_to_bytes() Philipp Zabel
2014-08-18 13:40 ` [PATCH 18/26] gpu: ipu-v3: Add ipu_idmac_enable_watermark() Philipp Zabel
2014-08-18 13:40 ` [PATCH 19/26] gpu: ipu-v3: Add ipu_idmac_lock_enable() Philipp Zabel
2014-08-18 13:40 ` [PATCH 20/26] gpu: ipu-cpmem: Add ipu_cpmem_set_block_mode() Philipp Zabel
2014-08-18 13:40 ` [PATCH 21/26] gpu: ipu-cpmem: Add ipu_cpmem_set_axi_id() Philipp Zabel
2014-08-18 13:40 ` [PATCH 22/26] gpu: ipu-cpmem: Add ipu_cpmem_set_rotation() Philipp Zabel
2014-08-18 13:40 ` [PATCH 23/26] gpu: ipu-cpmem: Add second buffer support to ipu_cpmem_set_image() Philipp Zabel
2014-08-18 13:40 ` [PATCH 24/26] gpu: ipu-v3: Add more planar formats support Philipp Zabel
2014-08-18 13:40 ` [PATCH 25/26] gpu: ipu-cpmem: Add ipu_cpmem_dump() Philipp Zabel
2014-08-18 13:40 ` [PATCH 26/26] gpu: ipu-v3: Add ipu_dump() Philipp Zabel
2014-08-19 17:37 ` [PATCH v2 00/26] IPUv3 prep for video capture Steve Longerbeam

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=53F38EE8.3020702@gmail.com \
    --to=slongerbeam@gmail.com \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=kernel@pengutronix.de \
    --cc=linux@arm.linux.org.uk \
    --cc=p.zabel@pengutronix.de \
    --cc=steve_longerbeam@mentor.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.