Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

+120 -1
+1 -1
drivers/gpu/ipu-v3/Makefile
··· 1 1 obj-$(CONFIG_IMX_IPUV3_CORE) += imx-ipu-v3.o 2 2 3 - imx-ipu-v3-objs := ipu-common.o ipu-dc.o ipu-di.o ipu-dp.o ipu-dmfc.o 3 + imx-ipu-v3-objs := ipu-common.o ipu-dc.o ipu-di.o ipu-dp.o ipu-dmfc.o ipu-smfc.o
+10
drivers/gpu/ipu-v3/ipu-common.c
··· 874 874 goto err_dp; 875 875 } 876 876 877 + ret = ipu_smfc_init(ipu, dev, ipu_base + 878 + devtype->cm_ofs + IPU_CM_SMFC_REG_OFS); 879 + if (ret) { 880 + unit = "smfc"; 881 + goto err_smfc; 882 + } 883 + 877 884 return 0; 878 885 886 + err_smfc: 887 + ipu_dp_exit(ipu); 879 888 err_dp: 880 889 ipu_dmfc_exit(ipu); 881 890 err_dmfc: ··· 956 947 957 948 static void ipu_submodules_exit(struct ipu_soc *ipu) 958 949 { 950 + ipu_smfc_exit(ipu); 959 951 ipu_dp_exit(ipu); 960 952 ipu_dmfc_exit(ipu); 961 953 ipu_dc_exit(ipu);
+6
drivers/gpu/ipu-v3/ipu-prv.h
··· 151 151 struct ipu_dc_priv; 152 152 struct ipu_dmfc_priv; 153 153 struct ipu_di; 154 + struct ipu_smfc_priv; 155 + 154 156 struct ipu_devtype; 155 157 156 158 struct ipu_soc { ··· 180 178 struct ipu_dp_priv *dp_priv; 181 179 struct ipu_dmfc_priv *dmfc_priv; 182 180 struct ipu_di *di_priv[2]; 181 + struct ipu_smfc_priv *smfc_priv; 183 182 }; 184 183 185 184 void ipu_srm_dp_sync_update(struct ipu_soc *ipu); ··· 205 202 206 203 int ipu_cpmem_init(struct ipu_soc *ipu, struct device *dev, unsigned long base); 207 204 void ipu_cpmem_exit(struct ipu_soc *ipu); 205 + 206 + int ipu_smfc_init(struct ipu_soc *ipu, struct device *dev, unsigned long base); 207 + void ipu_smfc_exit(struct ipu_soc *ipu); 208 208 209 209 #endif /* __IPU_PRV_H__ */
+97
drivers/gpu/ipu-v3/ipu-smfc.c
··· 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 + #define DEBUG 12 + #include <linux/export.h> 13 + #include <linux/types.h> 14 + #include <linux/init.h> 15 + #include <linux/io.h> 16 + #include <linux/errno.h> 17 + #include <linux/spinlock.h> 18 + #include <linux/delay.h> 19 + #include <linux/clk.h> 20 + #include <video/imx-ipu-v3.h> 21 + 22 + #include "ipu-prv.h" 23 + 24 + struct ipu_smfc_priv { 25 + void __iomem *base; 26 + spinlock_t lock; 27 + }; 28 + 29 + /*SMFC Registers */ 30 + #define SMFC_MAP 0x0000 31 + #define SMFC_WMC 0x0004 32 + #define SMFC_BS 0x0008 33 + 34 + int ipu_smfc_set_burstsize(struct ipu_soc *ipu, int channel, int burstsize) 35 + { 36 + struct ipu_smfc_priv *smfc = ipu->smfc_priv; 37 + unsigned long flags; 38 + u32 val, shift; 39 + 40 + spin_lock_irqsave(&smfc->lock, flags); 41 + 42 + shift = channel * 4; 43 + val = readl(smfc->base + SMFC_BS); 44 + val &= ~(0xf << shift); 45 + val |= burstsize << shift; 46 + writel(val, smfc->base + SMFC_BS); 47 + 48 + spin_unlock_irqrestore(&smfc->lock, flags); 49 + 50 + return 0; 51 + } 52 + EXPORT_SYMBOL_GPL(ipu_smfc_set_burstsize); 53 + 54 + int ipu_smfc_map_channel(struct ipu_soc *ipu, int channel, int csi_id, int mipi_id) 55 + { 56 + struct ipu_smfc_priv *smfc = ipu->smfc_priv; 57 + unsigned long flags; 58 + u32 val, shift; 59 + 60 + spin_lock_irqsave(&smfc->lock, flags); 61 + 62 + shift = channel * 3; 63 + val = readl(smfc->base + SMFC_MAP); 64 + val &= ~(0x7 << shift); 65 + val |= ((csi_id << 2) | mipi_id) << shift; 66 + writel(val, smfc->base + SMFC_MAP); 67 + 68 + spin_unlock_irqrestore(&smfc->lock, flags); 69 + 70 + return 0; 71 + } 72 + EXPORT_SYMBOL_GPL(ipu_smfc_map_channel); 73 + 74 + int ipu_smfc_init(struct ipu_soc *ipu, struct device *dev, 75 + unsigned long base) 76 + { 77 + struct ipu_smfc_priv *smfc; 78 + 79 + smfc = devm_kzalloc(dev, sizeof(*smfc), GFP_KERNEL); 80 + if (!smfc) 81 + return -ENOMEM; 82 + 83 + ipu->smfc_priv = smfc; 84 + spin_lock_init(&smfc->lock); 85 + 86 + smfc->base = devm_ioremap(dev, base, PAGE_SIZE); 87 + if (!smfc->base) 88 + return -ENOMEM; 89 + 90 + pr_debug("%s: ioremap 0x%08lx -> %p\n", __func__, base, smfc->base); 91 + 92 + return 0; 93 + } 94 + 95 + void ipu_smfc_exit(struct ipu_soc *ipu) 96 + { 97 + }
+6
include/video/imx-ipu-v3.h
··· 160 160 int ipu_dp_set_global_alpha(struct ipu_dp *dp, bool enable, u8 alpha, 161 161 bool bg_chan); 162 162 163 + /* 164 + * IPU Sensor Multiple FIFO Controller (SMFC) functions 165 + */ 166 + int ipu_smfc_map_channel(struct ipu_soc *ipu, int channel, int csi_id, int mipi_id); 167 + int ipu_smfc_set_burstsize(struct ipu_soc *ipu, int channel, int burstsize); 168 + 163 169 #define IPU_CPMEM_WORD(word, ofs, size) ((((word) * 160 + (ofs)) << 8) | (size)) 164 170 165 171 #define IPU_FIELD_UBO IPU_CPMEM_WORD(0, 46, 22)