diff options
author | Philipp Zabel <p.zabel@pengutronix.de> | 2012-05-09 18:59:01 +0400 |
---|---|---|
committer | Philipp Zabel <p.zabel@pengutronix.de> | 2014-06-04 13:07:10 +0400 |
commit | 35de925ffaa67971e073d3ebf1e0600be0d0d3f1 (patch) | |
tree | d43d07842882332430c4711b38baa2e7a161647d /drivers/gpu/ipu-v3/ipu-smfc.c | |
parent | 39b9004d1f626b88b775c7655d3f286e135dfec6 (diff) | |
download | linux-35de925ffaa67971e073d3ebf1e0600be0d0d3f1.tar.xz |
gpu: ipu-v3: Add SMFC code
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.zabel@pengutronix.de>
Diffstat (limited to 'drivers/gpu/ipu-v3/ipu-smfc.c')
-rw-r--r-- | drivers/gpu/ipu-v3/ipu-smfc.c | 97 |
1 files changed, 97 insertions, 0 deletions
diff --git a/drivers/gpu/ipu-v3/ipu-smfc.c b/drivers/gpu/ipu-v3/ipu-smfc.c new file mode 100644 index 000000000000..e4f85ad286fc --- /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) +{ +} |