diff options
author | Lucas Stach <l.stach@pengutronix.de> | 2017-03-08 06:13:16 -0500 |
---|---|---|
committer | Philipp Zabel <p.zabel@pengutronix.de> | 2017-03-16 05:14:02 -0400 |
commit | ea9c260514c15f14d43a4c099646c44238dccf1e (patch) | |
tree | 6186fab57b34db46e9f517747c3cc51c1759d49c | |
parent | 63863d43e8f98691a714673991884732db8c8487 (diff) |
gpu: ipu-v3: add driver for Prefetch Resolve Gasket
This adds support for the i.MX6 QUadPlus PRG unit. It glues together the
IPU and the PRE units.
Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
---
v4: add missing ipu_soc->prg_priv
-rw-r--r-- | drivers/gpu/ipu-v3/Makefile | 2 | ||||
-rw-r--r-- | drivers/gpu/ipu-v3/ipu-common.c | 1 | ||||
-rw-r--r-- | drivers/gpu/ipu-v3/ipu-prg.c | 424 | ||||
-rw-r--r-- | drivers/gpu/ipu-v3/ipu-prv.h | 6 | ||||
-rw-r--r-- | include/video/imx-ipu-v3.h | 15 |
5 files changed, 447 insertions, 1 deletions
diff --git a/drivers/gpu/ipu-v3/Makefile b/drivers/gpu/ipu-v3/Makefile index 8ae90de46b4d..1ab9bceee755 100644 --- a/drivers/gpu/ipu-v3/Makefile +++ b/drivers/gpu/ipu-v3/Makefile | |||
@@ -2,4 +2,4 @@ obj-$(CONFIG_IMX_IPUV3_CORE) += imx-ipu-v3.o | |||
2 | 2 | ||
3 | imx-ipu-v3-objs := ipu-common.o ipu-cpmem.o ipu-csi.o ipu-dc.o ipu-di.o \ | 3 | imx-ipu-v3-objs := ipu-common.o ipu-cpmem.o ipu-csi.o ipu-dc.o ipu-di.o \ |
4 | ipu-dp.o ipu-dmfc.o ipu-ic.o ipu-image-convert.o \ | 4 | ipu-dp.o ipu-dmfc.o ipu-ic.o ipu-image-convert.o \ |
5 | ipu-pre.o ipu-smfc.o ipu-vdi.o | 5 | ipu-pre.o ipu-prg.o ipu-smfc.o ipu-vdi.o |
diff --git a/drivers/gpu/ipu-v3/ipu-common.c b/drivers/gpu/ipu-v3/ipu-common.c index 7ae1b9739a7f..4c8453989746 100644 --- a/drivers/gpu/ipu-v3/ipu-common.c +++ b/drivers/gpu/ipu-v3/ipu-common.c | |||
@@ -1530,6 +1530,7 @@ static struct platform_driver imx_ipu_driver = { | |||
1530 | 1530 | ||
1531 | static struct platform_driver * const drivers[] = { | 1531 | static struct platform_driver * const drivers[] = { |
1532 | &ipu_pre_drv, | 1532 | &ipu_pre_drv, |
1533 | &ipu_prg_drv, | ||
1533 | &imx_ipu_driver, | 1534 | &imx_ipu_driver, |
1534 | }; | 1535 | }; |
1535 | 1536 | ||
diff --git a/drivers/gpu/ipu-v3/ipu-prg.c b/drivers/gpu/ipu-v3/ipu-prg.c new file mode 100644 index 000000000000..caca57febbd6 --- /dev/null +++ b/drivers/gpu/ipu-v3/ipu-prg.c | |||
@@ -0,0 +1,424 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2016-2017 Lucas Stach, Pengutronix | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify it | ||
5 | * under the terms and conditions of the GNU General Public License, | ||
6 | * version 2, as published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
11 | * more details. | ||
12 | */ | ||
13 | |||
14 | #include <drm/drm_fourcc.h> | ||
15 | #include <linux/clk.h> | ||
16 | #include <linux/err.h> | ||
17 | #include <linux/mfd/syscon.h> | ||
18 | #include <linux/mfd/syscon/imx6q-iomuxc-gpr.h> | ||
19 | #include <linux/module.h> | ||
20 | #include <linux/of.h> | ||
21 | #include <linux/platform_device.h> | ||
22 | #include <linux/regmap.h> | ||
23 | #include <video/imx-ipu-v3.h> | ||
24 | |||
25 | #include "ipu-prv.h" | ||
26 | |||
27 | #define IPU_PRG_CTL 0x00 | ||
28 | #define IPU_PRG_CTL_BYPASS(i) (1 << (0 + i)) | ||
29 | #define IPU_PRG_CTL_SOFT_ARID_MASK 0x3 | ||
30 | #define IPU_PRG_CTL_SOFT_ARID_SHIFT(i) (8 + i * 2) | ||
31 | #define IPU_PRG_CTL_SOFT_ARID(i, v) ((v & 0x3) << (8 + 2 * i)) | ||
32 | #define IPU_PRG_CTL_SO(i) (1 << (16 + i)) | ||
33 | #define IPU_PRG_CTL_VFLIP(i) (1 << (19 + i)) | ||
34 | #define IPU_PRG_CTL_BLOCK_MODE(i) (1 << (22 + i)) | ||
35 | #define IPU_PRG_CTL_CNT_LOAD_EN(i) (1 << (25 + i)) | ||
36 | #define IPU_PRG_CTL_SOFTRST (1 << 30) | ||
37 | #define IPU_PRG_CTL_SHADOW_EN (1 << 31) | ||
38 | |||
39 | #define IPU_PRG_STATUS 0x04 | ||
40 | #define IPU_PRG_STATUS_BUFFER0_READY(i) (1 << (0 + i * 2)) | ||
41 | #define IPU_PRG_STATUS_BUFFER1_READY(i) (1 << (1 + i * 2)) | ||
42 | |||
43 | #define IPU_PRG_QOS 0x08 | ||
44 | #define IPU_PRG_QOS_ARID_MASK 0xf | ||
45 | #define IPU_PRG_QOS_ARID_SHIFT(i) (0 + i * 4) | ||
46 | |||
47 | #define IPU_PRG_REG_UPDATE 0x0c | ||
48 | #define IPU_PRG_REG_UPDATE_REG_UPDATE (1 << 0) | ||
49 | |||
50 | #define IPU_PRG_STRIDE(i) (0x10 + i * 0x4) | ||
51 | #define IPU_PRG_STRIDE_STRIDE_MASK 0x3fff | ||
52 | |||
53 | #define IPU_PRG_CROP_LINE 0x1c | ||
54 | |||
55 | #define IPU_PRG_THD 0x20 | ||
56 | |||
57 | #define IPU_PRG_BADDR(i) (0x24 + i * 0x4) | ||
58 | |||
59 | #define IPU_PRG_OFFSET(i) (0x30 + i * 0x4) | ||
60 | |||
61 | #define IPU_PRG_ILO(i) (0x3c + i * 0x4) | ||
62 | |||
63 | #define IPU_PRG_HEIGHT(i) (0x48 + i * 0x4) | ||
64 | #define IPU_PRG_HEIGHT_PRE_HEIGHT_MASK 0xfff | ||
65 | #define IPU_PRG_HEIGHT_PRE_HEIGHT_SHIFT 0 | ||
66 | #define IPU_PRG_HEIGHT_IPU_HEIGHT_MASK 0xfff | ||
67 | #define IPU_PRG_HEIGHT_IPU_HEIGHT_SHIFT 16 | ||
68 | |||
69 | struct ipu_prg_channel { | ||
70 | bool enabled; | ||
71 | int used_pre; | ||
72 | }; | ||
73 | |||
74 | struct ipu_prg { | ||
75 | struct list_head list; | ||
76 | struct device *dev; | ||
77 | int id; | ||
78 | |||
79 | void __iomem *regs; | ||
80 | struct clk *clk_ipg, *clk_axi; | ||
81 | struct regmap *iomuxc_gpr; | ||
82 | struct ipu_pre *pres[3]; | ||
83 | |||
84 | struct ipu_prg_channel chan[3]; | ||
85 | }; | ||
86 | |||
87 | static DEFINE_MUTEX(ipu_prg_list_mutex); | ||
88 | static LIST_HEAD(ipu_prg_list); | ||
89 | |||
90 | struct ipu_prg * | ||
91 | ipu_prg_lookup_by_phandle(struct device *dev, const char *name, int ipu_id) | ||
92 | { | ||
93 | struct device_node *prg_node = of_parse_phandle(dev->of_node, | ||
94 | name, 0); | ||
95 | struct ipu_prg *prg; | ||
96 | |||
97 | mutex_lock(&ipu_prg_list_mutex); | ||
98 | list_for_each_entry(prg, &ipu_prg_list, list) { | ||
99 | if (prg_node == prg->dev->of_node) { | ||
100 | mutex_unlock(&ipu_prg_list_mutex); | ||
101 | device_link_add(dev, prg->dev, DL_FLAG_AUTOREMOVE); | ||
102 | prg->id = ipu_id; | ||
103 | return prg; | ||
104 | } | ||
105 | } | ||
106 | mutex_unlock(&ipu_prg_list_mutex); | ||
107 | |||
108 | return NULL; | ||
109 | } | ||
110 | |||
111 | int ipu_prg_max_active_channels(void) | ||
112 | { | ||
113 | return ipu_pre_get_available_count(); | ||
114 | } | ||
115 | EXPORT_SYMBOL_GPL(ipu_prg_max_active_channels); | ||
116 | |||
117 | bool ipu_prg_present(struct ipu_soc *ipu) | ||
118 | { | ||
119 | if (ipu->prg_priv) | ||
120 | return true; | ||
121 | |||
122 | return false; | ||
123 | } | ||
124 | EXPORT_SYMBOL_GPL(ipu_prg_present); | ||
125 | |||
126 | bool ipu_prg_format_supported(struct ipu_soc *ipu, uint32_t format, | ||
127 | uint64_t modifier) | ||
128 | { | ||
129 | const struct drm_format_info *info = drm_format_info(format); | ||
130 | |||
131 | if (info->num_planes != 1) | ||
132 | return false; | ||
133 | |||
134 | return true; | ||
135 | } | ||
136 | EXPORT_SYMBOL_GPL(ipu_prg_format_supported); | ||
137 | |||
138 | int ipu_prg_enable(struct ipu_soc *ipu) | ||
139 | { | ||
140 | struct ipu_prg *prg = ipu->prg_priv; | ||
141 | int ret; | ||
142 | |||
143 | if (!prg) | ||
144 | return 0; | ||
145 | |||
146 | ret = clk_prepare_enable(prg->clk_axi); | ||
147 | if (ret) | ||
148 | goto fail_disable_ipg; | ||
149 | |||
150 | return 0; | ||
151 | |||
152 | fail_disable_ipg: | ||
153 | clk_disable_unprepare(prg->clk_ipg); | ||
154 | |||
155 | return ret; | ||
156 | } | ||
157 | EXPORT_SYMBOL_GPL(ipu_prg_enable); | ||
158 | |||
159 | void ipu_prg_disable(struct ipu_soc *ipu) | ||
160 | { | ||
161 | struct ipu_prg *prg = ipu->prg_priv; | ||
162 | |||
163 | if (!prg) | ||
164 | return; | ||
165 | |||
166 | clk_disable_unprepare(prg->clk_axi); | ||
167 | } | ||
168 | EXPORT_SYMBOL_GPL(ipu_prg_disable); | ||
169 | |||
170 | /* | ||
171 | * The channel configuartion functions below are not thread safe, as they | ||
172 | * must be only called from the atomic commit path in the DRM driver, which | ||
173 | * is properly serialized. | ||
174 | */ | ||
175 | static int ipu_prg_ipu_to_prg_chan(int ipu_chan) | ||
176 | { | ||
177 | /* | ||
178 | * This isn't clearly documented in the RM, but IPU to PRG channel | ||
179 | * assignment is fixed, as only with this mapping the control signals | ||
180 | * match up. | ||
181 | */ | ||
182 | switch (ipu_chan) { | ||
183 | case IPUV3_CHANNEL_MEM_BG_SYNC: | ||
184 | return 0; | ||
185 | case IPUV3_CHANNEL_MEM_FG_SYNC: | ||
186 | return 1; | ||
187 | case IPUV3_CHANNEL_MEM_DC_SYNC: | ||
188 | return 2; | ||
189 | default: | ||
190 | return -EINVAL; | ||
191 | } | ||
192 | } | ||
193 | |||
194 | static int ipu_prg_get_pre(struct ipu_prg *prg, int prg_chan) | ||
195 | { | ||
196 | int i, ret; | ||
197 | |||
198 | /* channel 0 is special as it is hardwired to one of the PREs */ | ||
199 | if (prg_chan == 0) { | ||
200 | ret = ipu_pre_get(prg->pres[0]); | ||
201 | if (ret) | ||
202 | goto fail; | ||
203 | prg->chan[prg_chan].used_pre = 0; | ||
204 | return 0; | ||
205 | } | ||
206 | |||
207 | for (i = 1; i < 3; i++) { | ||
208 | ret = ipu_pre_get(prg->pres[i]); | ||
209 | if (!ret) { | ||
210 | u32 val, mux; | ||
211 | int shift; | ||
212 | |||
213 | prg->chan[prg_chan].used_pre = i; | ||
214 | |||
215 | /* configure the PRE to PRG channel mux */ | ||
216 | shift = (i == 1) ? 12 : 14; | ||
217 | mux = (prg->id << 1) | (prg_chan - 1); | ||
218 | regmap_update_bits(prg->iomuxc_gpr, IOMUXC_GPR5, | ||
219 | 0x3 << shift, mux << shift); | ||
220 | |||
221 | /* check other mux, must not point to same channel */ | ||
222 | shift = (i == 1) ? 14 : 12; | ||
223 | regmap_read(prg->iomuxc_gpr, IOMUXC_GPR5, &val); | ||
224 | if (((val >> shift) & 0x3) == mux) { | ||
225 | regmap_update_bits(prg->iomuxc_gpr, IOMUXC_GPR5, | ||
226 | 0x3 << shift, | ||
227 | (mux ^ 0x1) << shift); | ||
228 | } | ||
229 | |||
230 | return 0; | ||
231 | } | ||
232 | } | ||
233 | |||
234 | fail: | ||
235 | dev_err(prg->dev, "could not get PRE for PRG chan %d", prg_chan); | ||
236 | return ret; | ||
237 | } | ||
238 | |||
239 | static void ipu_prg_put_pre(struct ipu_prg *prg, int prg_chan) | ||
240 | { | ||
241 | struct ipu_prg_channel *chan = &prg->chan[prg_chan]; | ||
242 | |||
243 | ipu_pre_put(prg->pres[chan->used_pre]); | ||
244 | chan->used_pre = -1; | ||
245 | } | ||
246 | |||
247 | void ipu_prg_channel_disable(struct ipuv3_channel *ipu_chan) | ||
248 | { | ||
249 | int prg_chan = ipu_prg_ipu_to_prg_chan(ipu_chan->num); | ||
250 | struct ipu_prg *prg = ipu_chan->ipu->prg_priv; | ||
251 | struct ipu_prg_channel *chan = &prg->chan[prg_chan]; | ||
252 | u32 val; | ||
253 | |||
254 | if (!chan->enabled || prg_chan < 0) | ||
255 | return; | ||
256 | |||
257 | clk_prepare_enable(prg->clk_ipg); | ||
258 | |||
259 | val = readl(prg->regs + IPU_PRG_CTL); | ||
260 | val |= IPU_PRG_CTL_BYPASS(prg_chan); | ||
261 | writel(val, prg->regs + IPU_PRG_CTL); | ||
262 | |||
263 | val = IPU_PRG_REG_UPDATE_REG_UPDATE; | ||
264 | writel(val, prg->regs + IPU_PRG_REG_UPDATE); | ||
265 | |||
266 | clk_disable_unprepare(prg->clk_ipg); | ||
267 | |||
268 | ipu_prg_put_pre(prg, prg_chan); | ||
269 | |||
270 | chan->enabled = false; | ||
271 | } | ||
272 | EXPORT_SYMBOL_GPL(ipu_prg_channel_disable); | ||
273 | |||
274 | int ipu_prg_channel_configure(struct ipuv3_channel *ipu_chan, | ||
275 | unsigned int axi_id, unsigned int width, | ||
276 | unsigned int height, unsigned int stride, | ||
277 | u32 format, unsigned long *eba) | ||
278 | { | ||
279 | int prg_chan = ipu_prg_ipu_to_prg_chan(ipu_chan->num); | ||
280 | struct ipu_prg *prg = ipu_chan->ipu->prg_priv; | ||
281 | struct ipu_prg_channel *chan = &prg->chan[prg_chan]; | ||
282 | u32 val; | ||
283 | int ret; | ||
284 | |||
285 | if (prg_chan < 0) | ||
286 | return prg_chan; | ||
287 | |||
288 | if (chan->enabled) { | ||
289 | ipu_pre_update(prg->pres[chan->used_pre], *eba); | ||
290 | return 0; | ||
291 | } | ||
292 | |||
293 | ret = ipu_prg_get_pre(prg, prg_chan); | ||
294 | if (ret) | ||
295 | return ret; | ||
296 | |||
297 | ipu_pre_configure(prg->pres[chan->used_pre], | ||
298 | width, height, stride, format, *eba); | ||
299 | |||
300 | |||
301 | ret = clk_prepare_enable(prg->clk_ipg); | ||
302 | if (ret) { | ||
303 | ipu_prg_put_pre(prg, prg_chan); | ||
304 | return ret; | ||
305 | } | ||
306 | |||
307 | val = (stride - 1) & IPU_PRG_STRIDE_STRIDE_MASK; | ||
308 | writel(val, prg->regs + IPU_PRG_STRIDE(prg_chan)); | ||
309 | |||
310 | val = ((height & IPU_PRG_HEIGHT_PRE_HEIGHT_MASK) << | ||
311 | IPU_PRG_HEIGHT_PRE_HEIGHT_SHIFT) | | ||
312 | ((height & IPU_PRG_HEIGHT_IPU_HEIGHT_MASK) << | ||
313 | IPU_PRG_HEIGHT_IPU_HEIGHT_SHIFT); | ||
314 | writel(val, prg->regs + IPU_PRG_HEIGHT(prg_chan)); | ||
315 | |||
316 | val = ipu_pre_get_baddr(prg->pres[chan->used_pre]); | ||
317 | *eba = val; | ||
318 | writel(val, prg->regs + IPU_PRG_BADDR(prg_chan)); | ||
319 | |||
320 | val = readl(prg->regs + IPU_PRG_CTL); | ||
321 | /* counter load enable */ | ||
322 | val |= IPU_PRG_CTL_CNT_LOAD_EN(prg_chan); | ||
323 | /* config AXI ID */ | ||
324 | val &= ~(IPU_PRG_CTL_SOFT_ARID_MASK << | ||
325 | IPU_PRG_CTL_SOFT_ARID_SHIFT(prg_chan)); | ||
326 | val |= IPU_PRG_CTL_SOFT_ARID(prg_chan, axi_id); | ||
327 | /* enable channel */ | ||
328 | val &= ~IPU_PRG_CTL_BYPASS(prg_chan); | ||
329 | writel(val, prg->regs + IPU_PRG_CTL); | ||
330 | |||
331 | val = IPU_PRG_REG_UPDATE_REG_UPDATE; | ||
332 | writel(val, prg->regs + IPU_PRG_REG_UPDATE); | ||
333 | |||
334 | clk_disable_unprepare(prg->clk_ipg); | ||
335 | |||
336 | chan->enabled = true; | ||
337 | return 0; | ||
338 | } | ||
339 | EXPORT_SYMBOL_GPL(ipu_prg_channel_configure); | ||
340 | |||
341 | static int ipu_prg_probe(struct platform_device *pdev) | ||
342 | { | ||
343 | struct device *dev = &pdev->dev; | ||
344 | struct resource *res; | ||
345 | struct ipu_prg *prg; | ||
346 | u32 val; | ||
347 | int i, ret; | ||
348 | |||
349 | prg = devm_kzalloc(dev, sizeof(*prg), GFP_KERNEL); | ||
350 | if (!prg) | ||
351 | return -ENOMEM; | ||
352 | |||
353 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
354 | prg->regs = devm_ioremap_resource(&pdev->dev, res); | ||
355 | if (IS_ERR(prg->regs)) | ||
356 | return PTR_ERR(prg->regs); | ||
357 | |||
358 | |||
359 | prg->clk_ipg = devm_clk_get(dev, "ipg"); | ||
360 | if (IS_ERR(prg->clk_ipg)) | ||
361 | return PTR_ERR(prg->clk_ipg); | ||
362 | |||
363 | prg->clk_axi = devm_clk_get(dev, "axi"); | ||
364 | if (IS_ERR(prg->clk_axi)) | ||
365 | return PTR_ERR(prg->clk_axi); | ||
366 | |||
367 | prg->iomuxc_gpr = | ||
368 | syscon_regmap_lookup_by_compatible("fsl,imx6q-iomuxc-gpr"); | ||
369 | if (IS_ERR(prg->iomuxc_gpr)) | ||
370 | return PTR_ERR(prg->iomuxc_gpr); | ||
371 | |||
372 | for (i = 0; i < 3; i++) { | ||
373 | prg->pres[i] = ipu_pre_lookup_by_phandle(dev, "fsl,pres", i); | ||
374 | if (!prg->pres[i]) | ||
375 | return -EPROBE_DEFER; | ||
376 | } | ||
377 | |||
378 | ret = clk_prepare_enable(prg->clk_ipg); | ||
379 | if (ret) | ||
380 | return ret; | ||
381 | |||
382 | /* init to free running mode */ | ||
383 | val = readl(prg->regs + IPU_PRG_CTL); | ||
384 | val |= IPU_PRG_CTL_SHADOW_EN; | ||
385 | writel(val, prg->regs + IPU_PRG_CTL); | ||
386 | |||
387 | /* disable address threshold */ | ||
388 | writel(0xffffffff, prg->regs + IPU_PRG_THD); | ||
389 | |||
390 | clk_disable_unprepare(prg->clk_ipg); | ||
391 | |||
392 | prg->dev = dev; | ||
393 | platform_set_drvdata(pdev, prg); | ||
394 | mutex_lock(&ipu_prg_list_mutex); | ||
395 | list_add(&prg->list, &ipu_prg_list); | ||
396 | mutex_unlock(&ipu_prg_list_mutex); | ||
397 | |||
398 | return 0; | ||
399 | } | ||
400 | |||
401 | static int ipu_prg_remove(struct platform_device *pdev) | ||
402 | { | ||
403 | struct ipu_prg *prg = platform_get_drvdata(pdev); | ||
404 | |||
405 | mutex_lock(&ipu_prg_list_mutex); | ||
406 | list_del(&prg->list); | ||
407 | mutex_unlock(&ipu_prg_list_mutex); | ||
408 | |||
409 | return 0; | ||
410 | } | ||
411 | |||
412 | static const struct of_device_id ipu_prg_dt_ids[] = { | ||
413 | { .compatible = "fsl,imx6qp-prg", }, | ||
414 | { /* sentinel */ }, | ||
415 | }; | ||
416 | |||
417 | struct platform_driver ipu_prg_drv = { | ||
418 | .probe = ipu_prg_probe, | ||
419 | .remove = ipu_prg_remove, | ||
420 | .driver = { | ||
421 | .name = "imx-ipu-prg", | ||
422 | .of_match_table = ipu_prg_dt_ids, | ||
423 | }, | ||
424 | }; | ||
diff --git a/drivers/gpu/ipu-v3/ipu-prv.h b/drivers/gpu/ipu-v3/ipu-prv.h index 262efdff1dba..ca2a223a0d1e 100644 --- a/drivers/gpu/ipu-v3/ipu-prv.h +++ b/drivers/gpu/ipu-v3/ipu-prv.h | |||
@@ -174,6 +174,7 @@ struct ipu_vdi; | |||
174 | struct ipu_image_convert_priv; | 174 | struct ipu_image_convert_priv; |
175 | struct ipu_smfc_priv; | 175 | struct ipu_smfc_priv; |
176 | struct ipu_pre; | 176 | struct ipu_pre; |
177 | struct ipu_prg; | ||
177 | 178 | ||
178 | struct ipu_devtype; | 179 | struct ipu_devtype; |
179 | 180 | ||
@@ -208,6 +209,7 @@ struct ipu_soc { | |||
208 | struct ipu_vdi *vdi_priv; | 209 | struct ipu_vdi *vdi_priv; |
209 | struct ipu_image_convert_priv *image_convert_priv; | 210 | struct ipu_image_convert_priv *image_convert_priv; |
210 | struct ipu_smfc_priv *smfc_priv; | 211 | struct ipu_smfc_priv *smfc_priv; |
212 | struct ipu_prg *prg_priv; | ||
211 | }; | 213 | }; |
212 | 214 | ||
213 | static inline u32 ipu_idmac_read(struct ipu_soc *ipu, unsigned offset) | 215 | static inline u32 ipu_idmac_read(struct ipu_soc *ipu, unsigned offset) |
@@ -276,6 +278,10 @@ void ipu_pre_configure(struct ipu_pre *pre, unsigned int width, | |||
276 | unsigned int stride, u32 format, unsigned int bufaddr); | 278 | unsigned int stride, u32 format, unsigned int bufaddr); |
277 | void ipu_pre_update(struct ipu_pre *pre, unsigned int bufaddr); | 279 | void ipu_pre_update(struct ipu_pre *pre, unsigned int bufaddr); |
278 | 280 | ||
281 | struct ipu_prg *ipu_prg_lookup_by_phandle(struct device *dev, const char *name, | ||
282 | int ipu_id); | ||
283 | |||
279 | extern struct platform_driver ipu_pre_drv; | 284 | extern struct platform_driver ipu_pre_drv; |
285 | extern struct platform_driver ipu_prg_drv; | ||
280 | 286 | ||
281 | #endif /* __IPU_PRV_H__ */ | 287 | #endif /* __IPU_PRV_H__ */ |
diff --git a/include/video/imx-ipu-v3.h b/include/video/imx-ipu-v3.h index 6af74f0cf161..8cb07680fb41 100644 --- a/include/video/imx-ipu-v3.h +++ b/include/video/imx-ipu-v3.h | |||
@@ -331,6 +331,21 @@ int ipu_dp_set_global_alpha(struct ipu_dp *dp, bool enable, u8 alpha, | |||
331 | bool bg_chan); | 331 | bool bg_chan); |
332 | 332 | ||
333 | /* | 333 | /* |
334 | * IPU Prefetch Resolve Gasket (prg) functions | ||
335 | */ | ||
336 | int ipu_prg_max_active_channels(void); | ||
337 | bool ipu_prg_present(struct ipu_soc *ipu); | ||
338 | bool ipu_prg_format_supported(struct ipu_soc *ipu, uint32_t format, | ||
339 | uint64_t modifier); | ||
340 | int ipu_prg_enable(struct ipu_soc *ipu); | ||
341 | void ipu_prg_disable(struct ipu_soc *ipu); | ||
342 | void ipu_prg_channel_disable(struct ipuv3_channel *ipu_chan); | ||
343 | int ipu_prg_channel_configure(struct ipuv3_channel *ipu_chan, | ||
344 | unsigned int axi_id, unsigned int width, | ||
345 | unsigned int height, unsigned int stride, | ||
346 | u32 format, unsigned long *eba); | ||
347 | |||
348 | /* | ||
334 | * IPU CMOS Sensor Interface (csi) functions | 349 | * IPU CMOS Sensor Interface (csi) functions |
335 | */ | 350 | */ |
336 | struct ipu_csi; | 351 | struct ipu_csi; |