The Sensor Multi Fifo Controller (SMFC) is used as a buffer between
the two CSIs (writing simultaneously) and up to four IDMAC channels.

Signed-off-by: Philipp Zabel <p.za...@pengutronix.de>
---
 drivers/gpu/ipu-v3/Makefile     |  2 +-
 drivers/gpu/ipu-v3/ipu-common.c | 10 +++++
 drivers/gpu/ipu-v3/ipu-prv.h    |  6 +++
 drivers/gpu/ipu-v3/ipu-smfc.c   | 97 +++++++++++++++++++++++++++++++++++++++++
 include/video/imx-ipu-v3.h      |  6 +++
 5 files changed, 120 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/ipu-v3/ipu-smfc.c

diff --git a/drivers/gpu/ipu-v3/Makefile b/drivers/gpu/ipu-v3/Makefile
index d21cc37..1887972b 100644
--- a/drivers/gpu/ipu-v3/Makefile
+++ b/drivers/gpu/ipu-v3/Makefile
@@ -1,3 +1,3 @@
 obj-$(CONFIG_IMX_IPUV3_CORE) += imx-ipu-v3.o
 
-imx-ipu-v3-objs := ipu-common.o ipu-dc.o ipu-di.o ipu-dp.o ipu-dmfc.o
+imx-ipu-v3-objs := ipu-common.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 a59cc6c..8f98719 100644
--- a/drivers/gpu/ipu-v3/ipu-common.c
+++ b/drivers/gpu/ipu-v3/ipu-common.c
@@ -876,8 +876,17 @@ static int ipu_submodules_init(struct ipu_soc *ipu,
                goto err_dp;
        }
 
+       ret = ipu_smfc_init(ipu, dev, ipu_base +
+                       devtype->cm_ofs + IPU_CM_SMFC_REG_OFS);
+       if (ret) {
+               unit = "smfc";
+               goto err_smfc;
+       }
+
        return 0;
 
+err_smfc:
+       ipu_dp_exit(ipu);
 err_dp:
        ipu_dmfc_exit(ipu);
 err_dmfc:
@@ -949,6 +958,7 @@ EXPORT_SYMBOL_GPL(ipu_idmac_channel_irq);
 
 static void ipu_submodules_exit(struct ipu_soc *ipu)
 {
+       ipu_smfc_exit(ipu);
        ipu_dp_exit(ipu);
        ipu_dmfc_exit(ipu);
        ipu_dc_exit(ipu);
diff --git a/drivers/gpu/ipu-v3/ipu-prv.h b/drivers/gpu/ipu-v3/ipu-prv.h
index 5cb075f..acf1811 100644
--- a/drivers/gpu/ipu-v3/ipu-prv.h
+++ b/drivers/gpu/ipu-v3/ipu-prv.h
@@ -151,6 +151,8 @@ struct ipuv3_channel {
 struct ipu_dc_priv;
 struct ipu_dmfc_priv;
 struct ipu_di;
+struct ipu_smfc_priv;
+
 struct ipu_devtype;
 
 struct ipu_soc {
@@ -178,6 +180,7 @@ struct ipu_soc {
        struct ipu_dp_priv      *dp_priv;
        struct ipu_dmfc_priv    *dmfc_priv;
        struct ipu_di           *di_priv[2];
+       struct ipu_smfc_priv    *smfc_priv;
 };
 
 void ipu_srm_dp_sync_update(struct ipu_soc *ipu);
@@ -203,4 +206,7 @@ void ipu_dc_exit(struct ipu_soc *ipu);
 int ipu_cpmem_init(struct ipu_soc *ipu, struct device *dev, unsigned long 
base);
 void ipu_cpmem_exit(struct ipu_soc *ipu);
 
+int ipu_smfc_init(struct ipu_soc *ipu, struct device *dev, unsigned long base);
+void ipu_smfc_exit(struct ipu_soc *ipu);
+
 #endif                         /* __IPU_PRV_H__ */
diff --git a/drivers/gpu/ipu-v3/ipu-smfc.c b/drivers/gpu/ipu-v3/ipu-smfc.c
new file mode 100644
index 0000000..e4f85ad
--- /dev/null
+++ b/drivers/gpu/ipu-v3/ipu-smfc.c
@@ -0,0 +1,97 @@
+/*
+ * Copyright 2008-2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#define DEBUG
+#include <linux/export.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/errno.h>
+#include <linux/spinlock.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <video/imx-ipu-v3.h>
+
+#include "ipu-prv.h"
+
+struct ipu_smfc_priv {
+       void __iomem *base;
+       spinlock_t lock;
+};
+
+/*SMFC Registers */
+#define SMFC_MAP       0x0000
+#define SMFC_WMC       0x0004
+#define SMFC_BS                0x0008
+
+int ipu_smfc_set_burstsize(struct ipu_soc *ipu, int channel, int burstsize)
+{
+       struct ipu_smfc_priv *smfc = ipu->smfc_priv;
+       unsigned long flags;
+       u32 val, shift;
+
+       spin_lock_irqsave(&smfc->lock, flags);
+
+       shift = channel * 4;
+       val = readl(smfc->base + SMFC_BS);
+       val &= ~(0xf << shift);
+       val |= burstsize << shift;
+       writel(val, smfc->base + SMFC_BS);
+
+       spin_unlock_irqrestore(&smfc->lock, flags);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(ipu_smfc_set_burstsize);
+
+int ipu_smfc_map_channel(struct ipu_soc *ipu, int channel, int csi_id, int 
mipi_id)
+{
+       struct ipu_smfc_priv *smfc = ipu->smfc_priv;
+       unsigned long flags;
+       u32 val, shift;
+
+       spin_lock_irqsave(&smfc->lock, flags);
+
+       shift = channel * 3;
+       val = readl(smfc->base + SMFC_MAP);
+       val &= ~(0x7 << shift);
+       val |= ((csi_id << 2) | mipi_id) << shift;
+       writel(val, smfc->base + SMFC_MAP);
+
+       spin_unlock_irqrestore(&smfc->lock, flags);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(ipu_smfc_map_channel);
+
+int ipu_smfc_init(struct ipu_soc *ipu, struct device *dev,
+                 unsigned long base)
+{
+       struct ipu_smfc_priv *smfc;
+
+       smfc = devm_kzalloc(dev, sizeof(*smfc), GFP_KERNEL);
+       if (!smfc)
+               return -ENOMEM;
+
+       ipu->smfc_priv = smfc;
+       spin_lock_init(&smfc->lock);
+
+       smfc->base = devm_ioremap(dev, base, PAGE_SIZE);
+       if (!smfc->base)
+               return -ENOMEM;
+
+       pr_debug("%s: ioremap 0x%08lx -> %p\n", __func__, base, smfc->base);
+
+       return 0;
+}
+
+void ipu_smfc_exit(struct ipu_soc *ipu)
+{
+}
diff --git a/include/video/imx-ipu-v3.h b/include/video/imx-ipu-v3.h
index fb13823..274da71 100644
--- a/include/video/imx-ipu-v3.h
+++ b/include/video/imx-ipu-v3.h
@@ -160,6 +160,12 @@ int ipu_dp_set_window_pos(struct ipu_dp *, u16 x_pos, u16 
y_pos);
 int ipu_dp_set_global_alpha(struct ipu_dp *dp, bool enable, u8 alpha,
                bool bg_chan);
 
+/*
+ * IPU Sensor Multiple FIFO Controller (SMFC) functions
+ */
+int ipu_smfc_map_channel(struct ipu_soc *ipu, int channel, int csi_id, int 
mipi_id);
+int ipu_smfc_set_burstsize(struct ipu_soc *ipu, int channel, int burstsize);
+
 #define IPU_CPMEM_WORD(word, ofs, size) ((((word) * 160 + (ofs)) << 8) | 
(size))
 
 #define IPU_FIELD_UBO          IPU_CPMEM_WORD(0, 46, 22)
-- 
1.8.5.1

_______________________________________________
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel

Reply via email to