Author | Tokens | Token Proportion | Commits | Commit Proportion |
---|---|---|---|---|
Steve Longerbeam | 568 | 61.61% | 3 | 75.00% |
Philipp Zabel | 354 | 38.39% | 1 | 25.00% |
Total | 922 | 4 |
/* * 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 */ #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 { struct ipu_smfc_priv *priv; int chno; bool inuse; }; struct ipu_smfc_priv { void __iomem *base; spinlock_t lock; struct ipu_soc *ipu; struct ipu_smfc channel[4]; int use_count; }; /*SMFC Registers */ #define SMFC_MAP 0x0000 #define SMFC_WMC 0x0004 #define SMFC_BS 0x0008 int ipu_smfc_set_burstsize(struct ipu_smfc *smfc, int burstsize) { struct ipu_smfc_priv *priv = smfc->priv; unsigned long flags; u32 val, shift; spin_lock_irqsave(&priv->lock, flags); shift = smfc->chno * 4; val = readl(priv->base + SMFC_BS); val &= ~(0xf << shift); val |= burstsize << shift; writel(val, priv->base + SMFC_BS); spin_unlock_irqrestore(&priv->lock, flags); return 0; } EXPORT_SYMBOL_GPL(ipu_smfc_set_burstsize); int ipu_smfc_map_channel(struct ipu_smfc *smfc, int csi_id, int mipi_id) { struct ipu_smfc_priv *priv = smfc->priv; unsigned long flags; u32 val, shift; spin_lock_irqsave(&priv->lock, flags); shift = smfc->chno * 3; val = readl(priv->base + SMFC_MAP); val &= ~(0x7 << shift); val |= ((csi_id << 2) | mipi_id) << shift; writel(val, priv->base + SMFC_MAP); spin_unlock_irqrestore(&priv->lock, flags); return 0; } EXPORT_SYMBOL_GPL(ipu_smfc_map_channel); int ipu_smfc_set_watermark(struct ipu_smfc *smfc, u32 set_level, u32 clr_level) { struct ipu_smfc_priv *priv = smfc->priv; unsigned long flags; u32 val, shift; spin_lock_irqsave(&priv->lock, flags); shift = smfc->chno * 6 + (smfc->chno > 1 ? 4 : 0); val = readl(priv->base + SMFC_WMC); val &= ~(0x3f << shift); val |= ((clr_level << 3) | set_level) << shift; writel(val, priv->base + SMFC_WMC); spin_unlock_irqrestore(&priv->lock, flags); return 0; } EXPORT_SYMBOL_GPL(ipu_smfc_set_watermark); int ipu_smfc_enable(struct ipu_smfc *smfc) { struct ipu_smfc_priv *priv = smfc->priv; unsigned long flags; spin_lock_irqsave(&priv->lock, flags); if (!priv->use_count) ipu_module_enable(priv->ipu, IPU_CONF_SMFC_EN); priv->use_count++; spin_unlock_irqrestore(&priv->lock, flags); return 0; } EXPORT_SYMBOL_GPL(ipu_smfc_enable); int ipu_smfc_disable(struct ipu_smfc *smfc) { struct ipu_smfc_priv *priv = smfc->priv; unsigned long flags; spin_lock_irqsave(&priv->lock, flags); priv->use_count--; if (!priv->use_count) ipu_module_disable(priv->ipu, IPU_CONF_SMFC_EN); if (priv->use_count < 0) priv->use_count = 0; spin_unlock_irqrestore(&priv->lock, flags); return 0; } EXPORT_SYMBOL_GPL(ipu_smfc_disable); struct ipu_smfc *ipu_smfc_get(struct ipu_soc *ipu, unsigned int chno) { struct ipu_smfc_priv *priv = ipu->smfc_priv; struct ipu_smfc *smfc, *ret; unsigned long flags; if (chno >= 4) return ERR_PTR(-EINVAL); smfc = &priv->channel[chno]; ret = smfc; spin_lock_irqsave(&priv->lock, flags); if (smfc->inuse) { ret = ERR_PTR(-EBUSY); goto unlock; } smfc->inuse = true; unlock: spin_unlock_irqrestore(&priv->lock, flags); return ret; } EXPORT_SYMBOL_GPL(ipu_smfc_get); void ipu_smfc_put(struct ipu_smfc *smfc) { struct ipu_smfc_priv *priv = smfc->priv; unsigned long flags; spin_lock_irqsave(&priv->lock, flags); smfc->inuse = false; spin_unlock_irqrestore(&priv->lock, flags); } EXPORT_SYMBOL_GPL(ipu_smfc_put); int ipu_smfc_init(struct ipu_soc *ipu, struct device *dev, unsigned long base) { struct ipu_smfc_priv *priv; int i; priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; ipu->smfc_priv = priv; spin_lock_init(&priv->lock); priv->ipu = ipu; priv->base = devm_ioremap(dev, base, PAGE_SIZE); if (!priv->base) return -ENOMEM; for (i = 0; i < 4; i++) { priv->channel[i].priv = priv; priv->channel[i].chno = i; } pr_debug("%s: ioremap 0x%08lx -> %p\n", __func__, base, priv->base); return 0; } void ipu_smfc_exit(struct ipu_soc *ipu) { }
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with Cregit http://github.com/cregit/cregit
Version 2.0-RC1