diff options
author | Philipp Zabel <p.zabel@pengutronix.de> | 2012-05-09 10:59:01 -0400 |
---|---|---|
committer | Philipp Zabel <p.zabel@pengutronix.de> | 2014-06-04 05:07:10 -0400 |
commit | 35de925ffaa67971e073d3ebf1e0600be0d0d3f1 (patch) | |
tree | d43d07842882332430c4711b38baa2e7a161647d | |
parent | 39b9004d1f626b88b775c7655d3f286e135dfec6 (diff) |
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>
-rw-r--r-- | drivers/gpu/ipu-v3/Makefile | 2 | ||||
-rw-r--r-- | drivers/gpu/ipu-v3/ipu-common.c | 10 | ||||
-rw-r--r-- | drivers/gpu/ipu-v3/ipu-prv.h | 6 | ||||
-rw-r--r-- | drivers/gpu/ipu-v3/ipu-smfc.c | 97 | ||||
-rw-r--r-- | include/video/imx-ipu-v3.h | 6 |
5 files changed, 120 insertions, 1 deletions
diff --git a/drivers/gpu/ipu-v3/Makefile b/drivers/gpu/ipu-v3/Makefile index d21cc37d0498..1887972b4ac2 100644 --- a/drivers/gpu/ipu-v3/Makefile +++ b/drivers/gpu/ipu-v3/Makefile | |||
@@ -1,3 +1,3 @@ | |||
1 | obj-$(CONFIG_IMX_IPUV3_CORE) += imx-ipu-v3.o | 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 |
diff --git a/drivers/gpu/ipu-v3/ipu-common.c b/drivers/gpu/ipu-v3/ipu-common.c index 7e1f614e7fbc..2aecc474c478 100644 --- a/drivers/gpu/ipu-v3/ipu-common.c +++ b/drivers/gpu/ipu-v3/ipu-common.c | |||
@@ -874,8 +874,17 @@ static int ipu_submodules_init(struct ipu_soc *ipu, | |||
874 | goto err_dp; | 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 | return 0; | 884 | return 0; |
878 | 885 | ||
886 | err_smfc: | ||
887 | ipu_dp_exit(ipu); | ||
879 | err_dp: | 888 | err_dp: |
880 | ipu_dmfc_exit(ipu); | 889 | ipu_dmfc_exit(ipu); |
881 | err_dmfc: | 890 | err_dmfc: |
@@ -947,6 +956,7 @@ EXPORT_SYMBOL_GPL(ipu_idmac_channel_irq); | |||
947 | 956 | ||
948 | static void ipu_submodules_exit(struct ipu_soc *ipu) | 957 | static void ipu_submodules_exit(struct ipu_soc *ipu) |
949 | { | 958 | { |
959 | ipu_smfc_exit(ipu); | ||
950 | ipu_dp_exit(ipu); | 960 | ipu_dp_exit(ipu); |
951 | ipu_dmfc_exit(ipu); | 961 | ipu_dmfc_exit(ipu); |
952 | ipu_dc_exit(ipu); | 962 | ipu_dc_exit(ipu); |
diff --git a/drivers/gpu/ipu-v3/ipu-prv.h b/drivers/gpu/ipu-v3/ipu-prv.h index 5cb075fdd48c..acf181183f0b 100644 --- a/drivers/gpu/ipu-v3/ipu-prv.h +++ b/drivers/gpu/ipu-v3/ipu-prv.h | |||
@@ -151,6 +151,8 @@ struct ipuv3_channel { | |||
151 | struct ipu_dc_priv; | 151 | struct ipu_dc_priv; |
152 | struct ipu_dmfc_priv; | 152 | struct ipu_dmfc_priv; |
153 | struct ipu_di; | 153 | struct ipu_di; |
154 | struct ipu_smfc_priv; | ||
155 | |||
154 | struct ipu_devtype; | 156 | struct ipu_devtype; |
155 | 157 | ||
156 | struct ipu_soc { | 158 | struct ipu_soc { |
@@ -178,6 +180,7 @@ struct ipu_soc { | |||
178 | struct ipu_dp_priv *dp_priv; | 180 | struct ipu_dp_priv *dp_priv; |
179 | struct ipu_dmfc_priv *dmfc_priv; | 181 | struct ipu_dmfc_priv *dmfc_priv; |
180 | struct ipu_di *di_priv[2]; | 182 | struct ipu_di *di_priv[2]; |
183 | struct ipu_smfc_priv *smfc_priv; | ||
181 | }; | 184 | }; |
182 | 185 | ||
183 | void ipu_srm_dp_sync_update(struct ipu_soc *ipu); | 186 | void ipu_srm_dp_sync_update(struct ipu_soc *ipu); |
@@ -203,4 +206,7 @@ void ipu_dc_exit(struct ipu_soc *ipu); | |||
203 | int ipu_cpmem_init(struct ipu_soc *ipu, struct device *dev, unsigned long base); | 206 | int ipu_cpmem_init(struct ipu_soc *ipu, struct device *dev, unsigned long base); |
204 | void ipu_cpmem_exit(struct ipu_soc *ipu); | 207 | void ipu_cpmem_exit(struct ipu_soc *ipu); |
205 | 208 | ||
209 | int ipu_smfc_init(struct ipu_soc *ipu, struct device *dev, unsigned long base); | ||
210 | void ipu_smfc_exit(struct ipu_soc *ipu); | ||
211 | |||
206 | #endif /* __IPU_PRV_H__ */ | 212 | #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 000000000000..e4f85ad286fc --- /dev/null +++ b/drivers/gpu/ipu-v3/ipu-smfc.c | |||
@@ -0,0 +1,97 @@ | |||
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 | } | ||
diff --git a/include/video/imx-ipu-v3.h b/include/video/imx-ipu-v3.h index c4d14ead5837..e639387eee3f 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); | |||
160 | int ipu_dp_set_global_alpha(struct ipu_dp *dp, bool enable, u8 alpha, | 160 | int ipu_dp_set_global_alpha(struct ipu_dp *dp, bool enable, u8 alpha, |
161 | bool bg_chan); | 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 | #define IPU_CPMEM_WORD(word, ofs, size) ((((word) * 160 + (ofs)) << 8) | (size)) | 169 | #define IPU_CPMEM_WORD(word, ofs, size) ((((word) * 160 + (ofs)) << 8) | (size)) |
164 | 170 | ||
165 | #define IPU_FIELD_UBO IPU_CPMEM_WORD(0, 46, 22) | 171 | #define IPU_FIELD_UBO IPU_CPMEM_WORD(0, 46, 22) |