1 /* 2 * Copyright 2008-2010 Freescale Semiconductor, Inc. All Rights Reserved. 3 * 4 * The code contained herein is licensed under the GNU General Public 5 * License. You may obtain a copy of the GNU General Public License 6 * Version 2 or later at the following locations: 7 * 8 * http://www.opensource.org/licenses/gpl-license.html 9 * http://www.gnu.org/copyleft/gpl.html 10 */ 11 #include <linux/export.h> 12 #include <linux/types.h> 13 #include <linux/init.h> 14 #include <linux/io.h> 15 #include <linux/errno.h> 16 #include <linux/spinlock.h> 17 #include <linux/delay.h> 18 #include <linux/clk.h> 19 #include <video/imx-ipu-v3.h> 20 21 #include "ipu-prv.h" 22 23 struct ipu_smfc_priv { 24 void __iomem *base; 25 spinlock_t lock; 26 }; 27 28 /*SMFC Registers */ 29 #define SMFC_MAP 0x0000 30 #define SMFC_WMC 0x0004 31 #define SMFC_BS 0x0008 32 33 int ipu_smfc_set_burstsize(struct ipu_soc *ipu, int channel, int burstsize) 34 { 35 struct ipu_smfc_priv *smfc = ipu->smfc_priv; 36 unsigned long flags; 37 u32 val, shift; 38 39 spin_lock_irqsave(&smfc->lock, flags); 40 41 shift = channel * 4; 42 val = readl(smfc->base + SMFC_BS); 43 val &= ~(0xf << shift); 44 val |= burstsize << shift; 45 writel(val, smfc->base + SMFC_BS); 46 47 spin_unlock_irqrestore(&smfc->lock, flags); 48 49 return 0; 50 } 51 EXPORT_SYMBOL_GPL(ipu_smfc_set_burstsize); 52 53 int ipu_smfc_map_channel(struct ipu_soc *ipu, int channel, int csi_id, int mipi_id) 54 { 55 struct ipu_smfc_priv *smfc = ipu->smfc_priv; 56 unsigned long flags; 57 u32 val, shift; 58 59 spin_lock_irqsave(&smfc->lock, flags); 60 61 shift = channel * 3; 62 val = readl(smfc->base + SMFC_MAP); 63 val &= ~(0x7 << shift); 64 val |= ((csi_id << 2) | mipi_id) << shift; 65 writel(val, smfc->base + SMFC_MAP); 66 67 spin_unlock_irqrestore(&smfc->lock, flags); 68 69 return 0; 70 } 71 EXPORT_SYMBOL_GPL(ipu_smfc_map_channel); 72 73 int ipu_smfc_init(struct ipu_soc *ipu, struct device *dev, 74 unsigned long base) 75 { 76 struct ipu_smfc_priv *smfc; 77 78 smfc = devm_kzalloc(dev, sizeof(*smfc), GFP_KERNEL); 79 if (!smfc) 80 return -ENOMEM; 81 82 ipu->smfc_priv = smfc; 83 spin_lock_init(&smfc->lock); 84 85 smfc->base = devm_ioremap(dev, base, PAGE_SIZE); 86 if (!smfc->base) 87 return -ENOMEM; 88 89 pr_debug("%s: ioremap 0x%08lx -> %p\n", __func__, base, smfc->base); 90 91 return 0; 92 } 93 94 void ipu_smfc_exit(struct ipu_soc *ipu) 95 { 96 } 97