2 * Copyright (c) 2010 Sascha Hauer <s.hauer@pengutronix.de>
3 * Copyright (C) 2005-2009 Freescale Semiconductor, Inc.
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 #include <linux/module.h>
16 #include <linux/export.h>
17 #include <linux/types.h>
18 #include <linux/init.h>
19 #include <linux/platform_device.h>
20 #include <linux/err.h>
21 #include <linux/spinlock.h>
22 #include <linux/delay.h>
23 #include <linux/interrupt.h>
25 #include <linux/clk.h>
26 #include <linux/list.h>
27 #include <linux/irq.h>
28 #include <linux/irqchip/chained_irq.h>
29 #include <linux/of_device.h>
31 #include "imx-ipu-v3.h"
34 static inline u32
ipu_cm_read(struct ipu_soc
*ipu
, unsigned offset
)
36 return readl(ipu
->cm_reg
+ offset
);
39 static inline void ipu_cm_write(struct ipu_soc
*ipu
, u32 value
, unsigned offset
)
41 writel(value
, ipu
->cm_reg
+ offset
);
44 static inline u32
ipu_idmac_read(struct ipu_soc
*ipu
, unsigned offset
)
46 return readl(ipu
->idmac_reg
+ offset
);
49 static inline void ipu_idmac_write(struct ipu_soc
*ipu
, u32 value
,
52 writel(value
, ipu
->idmac_reg
+ offset
);
55 void ipu_srm_dp_sync_update(struct ipu_soc
*ipu
)
59 val
= ipu_cm_read(ipu
, IPU_SRM_PRI2
);
61 ipu_cm_write(ipu
, val
, IPU_SRM_PRI2
);
63 EXPORT_SYMBOL_GPL(ipu_srm_dp_sync_update
);
65 struct ipu_ch_param __iomem
*ipu_get_cpmem(struct ipuv3_channel
*channel
)
67 struct ipu_soc
*ipu
= channel
->ipu
;
69 return ipu
->cpmem_base
+ channel
->num
;
71 EXPORT_SYMBOL_GPL(ipu_get_cpmem
);
73 void ipu_cpmem_set_high_priority(struct ipuv3_channel
*channel
)
75 struct ipu_soc
*ipu
= channel
->ipu
;
76 struct ipu_ch_param __iomem
*p
= ipu_get_cpmem(channel
);
79 if (ipu
->ipu_type
== IPUV3EX
)
80 ipu_ch_param_write_field(p
, IPU_FIELD_ID
, 1);
82 val
= ipu_idmac_read(ipu
, IDMAC_CHA_PRI(channel
->num
));
83 val
|= 1 << (channel
->num
% 32);
84 ipu_idmac_write(ipu
, val
, IDMAC_CHA_PRI(channel
->num
));
86 EXPORT_SYMBOL_GPL(ipu_cpmem_set_high_priority
);
88 void ipu_ch_param_write_field(struct ipu_ch_param __iomem
*base
, u32 wbs
, u32 v
)
90 u32 bit
= (wbs
>> 8) % 160;
91 u32 size
= wbs
& 0xff;
92 u32 word
= (wbs
>> 8) / 160;
95 u32 mask
= (1 << size
) - 1;
98 pr_debug("%s %d %d %d\n", __func__
, word
, bit
, size
);
100 val
= readl(&base
->word
[word
].data
[i
]);
101 val
&= ~(mask
<< ofs
);
103 writel(val
, &base
->word
[word
].data
[i
]);
105 if ((bit
+ size
- 1) / 32 > i
) {
106 val
= readl(&base
->word
[word
].data
[i
+ 1]);
107 val
&= ~(mask
>> (ofs
? (32 - ofs
) : 0));
108 val
|= v
>> (ofs
? (32 - ofs
) : 0);
109 writel(val
, &base
->word
[word
].data
[i
+ 1]);
112 EXPORT_SYMBOL_GPL(ipu_ch_param_write_field
);
114 u32
ipu_ch_param_read_field(struct ipu_ch_param __iomem
*base
, u32 wbs
)
116 u32 bit
= (wbs
>> 8) % 160;
117 u32 size
= wbs
& 0xff;
118 u32 word
= (wbs
>> 8) / 160;
121 u32 mask
= (1 << size
) - 1;
124 pr_debug("%s %d %d %d\n", __func__
, word
, bit
, size
);
126 val
= (readl(&base
->word
[word
].data
[i
]) >> ofs
) & mask
;
128 if ((bit
+ size
- 1) / 32 > i
) {
130 tmp
= readl(&base
->word
[word
].data
[i
+ 1]);
131 tmp
&= mask
>> (ofs
? (32 - ofs
) : 0);
132 val
|= tmp
<< (ofs
? (32 - ofs
) : 0);
137 EXPORT_SYMBOL_GPL(ipu_ch_param_read_field
);
139 int ipu_cpmem_set_format_rgb(struct ipu_ch_param __iomem
*p
,
142 int bpp
= 0, npb
= 0, ro
, go
, bo
, to
;
144 ro
= rgb
->bits_per_pixel
- rgb
->red
.length
- rgb
->red
.offset
;
145 go
= rgb
->bits_per_pixel
- rgb
->green
.length
- rgb
->green
.offset
;
146 bo
= rgb
->bits_per_pixel
- rgb
->blue
.length
- rgb
->blue
.offset
;
147 to
= rgb
->bits_per_pixel
- rgb
->transp
.length
- rgb
->transp
.offset
;
149 ipu_ch_param_write_field(p
, IPU_FIELD_WID0
, rgb
->red
.length
- 1);
150 ipu_ch_param_write_field(p
, IPU_FIELD_OFS0
, ro
);
151 ipu_ch_param_write_field(p
, IPU_FIELD_WID1
, rgb
->green
.length
- 1);
152 ipu_ch_param_write_field(p
, IPU_FIELD_OFS1
, go
);
153 ipu_ch_param_write_field(p
, IPU_FIELD_WID2
, rgb
->blue
.length
- 1);
154 ipu_ch_param_write_field(p
, IPU_FIELD_OFS2
, bo
);
156 if (rgb
->transp
.length
) {
157 ipu_ch_param_write_field(p
, IPU_FIELD_WID3
,
158 rgb
->transp
.length
- 1);
159 ipu_ch_param_write_field(p
, IPU_FIELD_OFS3
, to
);
161 ipu_ch_param_write_field(p
, IPU_FIELD_WID3
, 7);
162 ipu_ch_param_write_field(p
, IPU_FIELD_OFS3
,
163 rgb
->bits_per_pixel
);
166 switch (rgb
->bits_per_pixel
) {
186 ipu_ch_param_write_field(p
, IPU_FIELD_BPP
, bpp
);
187 ipu_ch_param_write_field(p
, IPU_FIELD_NPB
, npb
);
188 ipu_ch_param_write_field(p
, IPU_FIELD_PFS
, 7); /* rgb mode */
192 EXPORT_SYMBOL_GPL(ipu_cpmem_set_format_rgb
);
194 int ipu_cpmem_set_format_passthrough(struct ipu_ch_param __iomem
*p
,
197 int bpp
= 0, npb
= 0;
220 ipu_ch_param_write_field(p
, IPU_FIELD_BPP
, bpp
);
221 ipu_ch_param_write_field(p
, IPU_FIELD_NPB
, npb
);
222 ipu_ch_param_write_field(p
, IPU_FIELD_PFS
, 6); /* raw mode */
226 EXPORT_SYMBOL_GPL(ipu_cpmem_set_format_passthrough
);
228 void ipu_cpmem_set_yuv_interleaved(struct ipu_ch_param __iomem
*p
,
231 switch (pixel_format
) {
232 case V4L2_PIX_FMT_UYVY
:
233 ipu_ch_param_write_field(p
, IPU_FIELD_BPP
, 3); /* bits/pixel */
234 ipu_ch_param_write_field(p
, IPU_FIELD_PFS
, 0xA); /* pix format */
235 ipu_ch_param_write_field(p
, IPU_FIELD_NPB
, 31); /* burst size */
237 case V4L2_PIX_FMT_YUYV
:
238 ipu_ch_param_write_field(p
, IPU_FIELD_BPP
, 3); /* bits/pixel */
239 ipu_ch_param_write_field(p
, IPU_FIELD_PFS
, 0x8); /* pix format */
240 ipu_ch_param_write_field(p
, IPU_FIELD_NPB
, 31); /* burst size */
244 EXPORT_SYMBOL_GPL(ipu_cpmem_set_yuv_interleaved
);
246 void ipu_cpmem_set_yuv_planar_full(struct ipu_ch_param __iomem
*p
,
247 u32 pixel_format
, int stride
, int u_offset
, int v_offset
)
249 switch (pixel_format
) {
250 case V4L2_PIX_FMT_YUV420
:
251 ipu_ch_param_write_field(p
, IPU_FIELD_SLUV
, (stride
/ 2) - 1);
252 ipu_ch_param_write_field(p
, IPU_FIELD_UBO
, u_offset
/ 8);
253 ipu_ch_param_write_field(p
, IPU_FIELD_VBO
, v_offset
/ 8);
255 case V4L2_PIX_FMT_YVU420
:
256 ipu_ch_param_write_field(p
, IPU_FIELD_SLUV
, (stride
/ 2) - 1);
257 ipu_ch_param_write_field(p
, IPU_FIELD_UBO
, v_offset
/ 8);
258 ipu_ch_param_write_field(p
, IPU_FIELD_VBO
, u_offset
/ 8);
262 EXPORT_SYMBOL_GPL(ipu_cpmem_set_yuv_planar_full
);
264 void ipu_cpmem_set_yuv_planar(struct ipu_ch_param __iomem
*p
, u32 pixel_format
,
265 int stride
, int height
)
267 int u_offset
, v_offset
;
270 switch (pixel_format
) {
271 case V4L2_PIX_FMT_YUV420
:
272 case V4L2_PIX_FMT_YVU420
:
273 uv_stride
= stride
/ 2;
274 u_offset
= stride
* height
;
275 v_offset
= u_offset
+ (uv_stride
* height
/ 2);
276 ipu_cpmem_set_yuv_planar_full(p
, pixel_format
, stride
,
281 EXPORT_SYMBOL_GPL(ipu_cpmem_set_yuv_planar
);
283 static struct ipu_rgb def_rgb_32
= {
284 .red
= { .offset
= 16, .length
= 8, },
285 .green
= { .offset
= 8, .length
= 8, },
286 .blue
= { .offset
= 0, .length
= 8, },
287 .transp
= { .offset
= 24, .length
= 8, },
288 .bits_per_pixel
= 32,
291 static struct ipu_rgb def_bgr_32
= {
292 .red
= { .offset
= 16, .length
= 8, },
293 .green
= { .offset
= 8, .length
= 8, },
294 .blue
= { .offset
= 0, .length
= 8, },
295 .transp
= { .offset
= 24, .length
= 8, },
296 .bits_per_pixel
= 32,
299 static struct ipu_rgb def_rgb_24
= {
300 .red
= { .offset
= 0, .length
= 8, },
301 .green
= { .offset
= 8, .length
= 8, },
302 .blue
= { .offset
= 16, .length
= 8, },
303 .transp
= { .offset
= 0, .length
= 0, },
304 .bits_per_pixel
= 24,
307 static struct ipu_rgb def_bgr_24
= {
308 .red
= { .offset
= 16, .length
= 8, },
309 .green
= { .offset
= 8, .length
= 8, },
310 .blue
= { .offset
= 0, .length
= 8, },
311 .transp
= { .offset
= 0, .length
= 0, },
312 .bits_per_pixel
= 24,
315 static struct ipu_rgb def_rgb_16
= {
316 .red
= { .offset
= 11, .length
= 5, },
317 .green
= { .offset
= 5, .length
= 6, },
318 .blue
= { .offset
= 0, .length
= 5, },
319 .transp
= { .offset
= 0, .length
= 0, },
320 .bits_per_pixel
= 16,
323 #define Y_OFFSET(pix, x, y) ((x) + pix->width * (y))
324 #define U_OFFSET(pix, x, y) ((pix->width * pix->height) + \
325 (pix->width * (y) / 4) + (x) / 2)
326 #define V_OFFSET(pix, x, y) ((pix->width * pix->height) + \
327 (pix->width * pix->height / 4) + \
328 (pix->width * (y) / 4) + (x) / 2)
330 int ipu_cpmem_set_fmt(struct ipu_ch_param __iomem
*cpmem
, u32 pixelformat
)
332 switch (pixelformat
) {
333 case V4L2_PIX_FMT_YUV420
:
334 case V4L2_PIX_FMT_YVU420
:
336 ipu_ch_param_write_field(cpmem
, IPU_FIELD_PFS
, 2);
338 ipu_ch_param_write_field(cpmem
, IPU_FIELD_NPB
, 63);
340 case V4L2_PIX_FMT_UYVY
:
342 ipu_ch_param_write_field(cpmem
, IPU_FIELD_BPP
, 3);
344 ipu_ch_param_write_field(cpmem
, IPU_FIELD_PFS
, 0xA);
346 ipu_ch_param_write_field(cpmem
, IPU_FIELD_NPB
, 31);
348 case V4L2_PIX_FMT_YUYV
:
350 ipu_ch_param_write_field(cpmem
, IPU_FIELD_BPP
, 3);
352 ipu_ch_param_write_field(cpmem
, IPU_FIELD_PFS
, 0x8);
354 ipu_ch_param_write_field(cpmem
, IPU_FIELD_NPB
, 31);
356 case V4L2_PIX_FMT_RGB32
:
357 ipu_cpmem_set_format_rgb(cpmem
, &def_rgb_32
);
359 case V4L2_PIX_FMT_RGB565
:
360 ipu_cpmem_set_format_rgb(cpmem
, &def_rgb_16
);
362 case V4L2_PIX_FMT_BGR32
:
363 ipu_cpmem_set_format_rgb(cpmem
, &def_bgr_32
);
365 case V4L2_PIX_FMT_RGB24
:
366 ipu_cpmem_set_format_rgb(cpmem
, &def_rgb_24
);
368 case V4L2_PIX_FMT_BGR24
:
369 ipu_cpmem_set_format_rgb(cpmem
, &def_bgr_24
);
377 EXPORT_SYMBOL_GPL(ipu_cpmem_set_fmt
);
379 int ipu_cpmem_set_image(struct ipu_ch_param __iomem
*cpmem
,
380 struct ipu_image
*image
)
382 struct v4l2_pix_format
*pix
= &image
->pix
;
383 int y_offset
, u_offset
, v_offset
;
385 pr_debug("%s: resolution: %dx%d stride: %d\n",
386 __func__
, pix
->width
, pix
->height
,
389 ipu_cpmem_set_resolution(cpmem
, image
->rect
.width
,
391 ipu_cpmem_set_stride(cpmem
, pix
->bytesperline
);
393 ipu_cpmem_set_fmt(cpmem
, pix
->pixelformat
);
395 switch (pix
->pixelformat
) {
396 case V4L2_PIX_FMT_YUV420
:
397 case V4L2_PIX_FMT_YVU420
:
398 y_offset
= Y_OFFSET(pix
, image
->rect
.left
, image
->rect
.top
);
399 u_offset
= U_OFFSET(pix
, image
->rect
.left
,
400 image
->rect
.top
) - y_offset
;
401 v_offset
= V_OFFSET(pix
, image
->rect
.left
,
402 image
->rect
.top
) - y_offset
;
404 ipu_cpmem_set_yuv_planar_full(cpmem
, pix
->pixelformat
,
405 pix
->bytesperline
, u_offset
, v_offset
);
406 ipu_cpmem_set_buffer(cpmem
, 0, image
->phys
+ y_offset
);
408 case V4L2_PIX_FMT_UYVY
:
409 case V4L2_PIX_FMT_YUYV
:
410 ipu_cpmem_set_buffer(cpmem
, 0, image
->phys
+
411 image
->rect
.left
* 2 +
412 image
->rect
.top
* image
->pix
.bytesperline
);
414 case V4L2_PIX_FMT_RGB32
:
415 case V4L2_PIX_FMT_BGR32
:
416 ipu_cpmem_set_buffer(cpmem
, 0, image
->phys
+
417 image
->rect
.left
* 4 +
418 image
->rect
.top
* image
->pix
.bytesperline
);
420 case V4L2_PIX_FMT_RGB565
:
421 ipu_cpmem_set_buffer(cpmem
, 0, image
->phys
+
422 image
->rect
.left
* 2 +
423 image
->rect
.top
* image
->pix
.bytesperline
);
425 case V4L2_PIX_FMT_RGB24
:
426 case V4L2_PIX_FMT_BGR24
:
427 ipu_cpmem_set_buffer(cpmem
, 0, image
->phys
+
428 image
->rect
.left
* 3 +
429 image
->rect
.top
* image
->pix
.bytesperline
);
437 EXPORT_SYMBOL_GPL(ipu_cpmem_set_image
);
439 enum ipu_color_space
ipu_pixelformat_to_colorspace(u32 pixelformat
)
441 switch (pixelformat
) {
442 case V4L2_PIX_FMT_YUV420
:
443 case V4L2_PIX_FMT_YVU420
:
444 case V4L2_PIX_FMT_UYVY
:
445 case V4L2_PIX_FMT_YUYV
:
446 return IPUV3_COLORSPACE_YUV
;
447 case V4L2_PIX_FMT_RGB32
:
448 case V4L2_PIX_FMT_BGR32
:
449 case V4L2_PIX_FMT_RGB24
:
450 case V4L2_PIX_FMT_BGR24
:
451 case V4L2_PIX_FMT_RGB565
:
452 return IPUV3_COLORSPACE_RGB
;
454 return IPUV3_COLORSPACE_UNKNOWN
;
457 EXPORT_SYMBOL_GPL(ipu_pixelformat_to_colorspace
);
459 struct ipuv3_channel
*ipu_idmac_get(struct ipu_soc
*ipu
, unsigned num
)
461 struct ipuv3_channel
*channel
;
463 dev_dbg(ipu
->dev
, "%s %d\n", __func__
, num
);
466 return ERR_PTR(-ENODEV
);
468 mutex_lock(&ipu
->channel_lock
);
470 channel
= &ipu
->channel
[num
];
473 channel
= ERR_PTR(-EBUSY
);
481 mutex_unlock(&ipu
->channel_lock
);
485 EXPORT_SYMBOL_GPL(ipu_idmac_get
);
487 void ipu_idmac_put(struct ipuv3_channel
*channel
)
489 struct ipu_soc
*ipu
= channel
->ipu
;
491 dev_dbg(ipu
->dev
, "%s %d\n", __func__
, channel
->num
);
493 mutex_lock(&ipu
->channel_lock
);
497 mutex_unlock(&ipu
->channel_lock
);
499 EXPORT_SYMBOL_GPL(ipu_idmac_put
);
501 #define idma_mask(ch) (1 << (ch & 0x1f))
503 void ipu_idmac_set_double_buffer(struct ipuv3_channel
*channel
,
506 struct ipu_soc
*ipu
= channel
->ipu
;
510 spin_lock_irqsave(&ipu
->lock
, flags
);
512 reg
= ipu_cm_read(ipu
, IPU_CHA_DB_MODE_SEL(channel
->num
));
514 reg
|= idma_mask(channel
->num
);
516 reg
&= ~idma_mask(channel
->num
);
517 ipu_cm_write(ipu
, reg
, IPU_CHA_DB_MODE_SEL(channel
->num
));
519 spin_unlock_irqrestore(&ipu
->lock
, flags
);
521 EXPORT_SYMBOL_GPL(ipu_idmac_set_double_buffer
);
523 int ipu_module_enable(struct ipu_soc
*ipu
, u32 mask
)
525 unsigned long lock_flags
;
528 spin_lock_irqsave(&ipu
->lock
, lock_flags
);
530 val
= ipu_cm_read(ipu
, IPU_DISP_GEN
);
532 if (mask
& IPU_CONF_DI0_EN
)
533 val
|= IPU_DI0_COUNTER_RELEASE
;
534 if (mask
& IPU_CONF_DI1_EN
)
535 val
|= IPU_DI1_COUNTER_RELEASE
;
537 ipu_cm_write(ipu
, val
, IPU_DISP_GEN
);
539 val
= ipu_cm_read(ipu
, IPU_CONF
);
541 ipu_cm_write(ipu
, val
, IPU_CONF
);
543 spin_unlock_irqrestore(&ipu
->lock
, lock_flags
);
547 EXPORT_SYMBOL_GPL(ipu_module_enable
);
549 int ipu_module_disable(struct ipu_soc
*ipu
, u32 mask
)
551 unsigned long lock_flags
;
554 spin_lock_irqsave(&ipu
->lock
, lock_flags
);
556 val
= ipu_cm_read(ipu
, IPU_CONF
);
558 ipu_cm_write(ipu
, val
, IPU_CONF
);
560 val
= ipu_cm_read(ipu
, IPU_DISP_GEN
);
562 if (mask
& IPU_CONF_DI0_EN
)
563 val
&= ~IPU_DI0_COUNTER_RELEASE
;
564 if (mask
& IPU_CONF_DI1_EN
)
565 val
&= ~IPU_DI1_COUNTER_RELEASE
;
567 ipu_cm_write(ipu
, val
, IPU_DISP_GEN
);
569 spin_unlock_irqrestore(&ipu
->lock
, lock_flags
);
573 EXPORT_SYMBOL_GPL(ipu_module_disable
);
575 void ipu_idmac_select_buffer(struct ipuv3_channel
*channel
, u32 buf_num
)
577 struct ipu_soc
*ipu
= channel
->ipu
;
578 unsigned int chno
= channel
->num
;
581 spin_lock_irqsave(&ipu
->lock
, flags
);
583 /* Mark buffer as ready. */
585 ipu_cm_write(ipu
, idma_mask(chno
), IPU_CHA_BUF0_RDY(chno
));
587 ipu_cm_write(ipu
, idma_mask(chno
), IPU_CHA_BUF1_RDY(chno
));
589 spin_unlock_irqrestore(&ipu
->lock
, flags
);
591 EXPORT_SYMBOL_GPL(ipu_idmac_select_buffer
);
593 int ipu_idmac_enable_channel(struct ipuv3_channel
*channel
)
595 struct ipu_soc
*ipu
= channel
->ipu
;
599 spin_lock_irqsave(&ipu
->lock
, flags
);
601 val
= ipu_idmac_read(ipu
, IDMAC_CHA_EN(channel
->num
));
602 val
|= idma_mask(channel
->num
);
603 ipu_idmac_write(ipu
, val
, IDMAC_CHA_EN(channel
->num
));
605 spin_unlock_irqrestore(&ipu
->lock
, flags
);
609 EXPORT_SYMBOL_GPL(ipu_idmac_enable_channel
);
611 int ipu_idmac_disable_channel(struct ipuv3_channel
*channel
)
613 struct ipu_soc
*ipu
= channel
->ipu
;
616 unsigned long timeout
;
618 timeout
= jiffies
+ msecs_to_jiffies(50);
619 while (ipu_idmac_read(ipu
, IDMAC_CHA_BUSY(channel
->num
)) &
620 idma_mask(channel
->num
)) {
621 if (time_after(jiffies
, timeout
)) {
622 dev_warn(ipu
->dev
, "disabling busy idmac channel %d\n",
629 spin_lock_irqsave(&ipu
->lock
, flags
);
631 /* Disable DMA channel(s) */
632 val
= ipu_idmac_read(ipu
, IDMAC_CHA_EN(channel
->num
));
633 val
&= ~idma_mask(channel
->num
);
634 ipu_idmac_write(ipu
, val
, IDMAC_CHA_EN(channel
->num
));
636 /* Set channel buffers NOT to be ready */
637 ipu_cm_write(ipu
, 0xf0000000, IPU_GPR
); /* write one to clear */
639 if (ipu_cm_read(ipu
, IPU_CHA_BUF0_RDY(channel
->num
)) &
640 idma_mask(channel
->num
)) {
641 ipu_cm_write(ipu
, idma_mask(channel
->num
),
642 IPU_CHA_BUF0_RDY(channel
->num
));
645 if (ipu_cm_read(ipu
, IPU_CHA_BUF1_RDY(channel
->num
)) &
646 idma_mask(channel
->num
)) {
647 ipu_cm_write(ipu
, idma_mask(channel
->num
),
648 IPU_CHA_BUF1_RDY(channel
->num
));
651 ipu_cm_write(ipu
, 0x0, IPU_GPR
); /* write one to set */
653 /* Reset the double buffer */
654 val
= ipu_cm_read(ipu
, IPU_CHA_DB_MODE_SEL(channel
->num
));
655 val
&= ~idma_mask(channel
->num
);
656 ipu_cm_write(ipu
, val
, IPU_CHA_DB_MODE_SEL(channel
->num
));
658 spin_unlock_irqrestore(&ipu
->lock
, flags
);
662 EXPORT_SYMBOL_GPL(ipu_idmac_disable_channel
);
664 static int ipu_reset(struct ipu_soc
*ipu
)
666 unsigned long timeout
;
668 ipu_cm_write(ipu
, 0x807FFFFF, IPU_MEM_RST
);
670 timeout
= jiffies
+ msecs_to_jiffies(1000);
671 while (ipu_cm_read(ipu
, IPU_MEM_RST
) & 0x80000000) {
672 if (time_after(jiffies
, timeout
))
682 unsigned long cm_ofs
;
683 unsigned long cpmem_ofs
;
684 unsigned long srm_ofs
;
685 unsigned long tpm_ofs
;
686 unsigned long disp0_ofs
;
687 unsigned long disp1_ofs
;
688 unsigned long dc_tmpl_ofs
;
689 unsigned long vdi_ofs
;
690 enum ipuv3_type type
;
693 static struct ipu_devtype ipu_type_imx51
= {
695 .cm_ofs
= 0x1e000000,
696 .cpmem_ofs
= 0x1f000000,
697 .srm_ofs
= 0x1f040000,
698 .tpm_ofs
= 0x1f060000,
699 .disp0_ofs
= 0x1e040000,
700 .disp1_ofs
= 0x1e048000,
701 .dc_tmpl_ofs
= 0x1f080000,
702 .vdi_ofs
= 0x1e068000,
706 static struct ipu_devtype ipu_type_imx53
= {
708 .cm_ofs
= 0x06000000,
709 .cpmem_ofs
= 0x07000000,
710 .srm_ofs
= 0x07040000,
711 .tpm_ofs
= 0x07060000,
712 .disp0_ofs
= 0x06040000,
713 .disp1_ofs
= 0x06048000,
714 .dc_tmpl_ofs
= 0x07080000,
715 .vdi_ofs
= 0x06068000,
719 static struct ipu_devtype ipu_type_imx6q
= {
721 .cm_ofs
= 0x00200000,
722 .cpmem_ofs
= 0x00300000,
723 .srm_ofs
= 0x00340000,
724 .tpm_ofs
= 0x00360000,
725 .disp0_ofs
= 0x00240000,
726 .disp1_ofs
= 0x00248000,
727 .dc_tmpl_ofs
= 0x00380000,
728 .vdi_ofs
= 0x00268000,
732 static const struct of_device_id imx_ipu_dt_ids
[] = {
733 { .compatible
= "fsl,imx51-ipu", .data
= &ipu_type_imx51
, },
734 { .compatible
= "fsl,imx53-ipu", .data
= &ipu_type_imx53
, },
735 { .compatible
= "fsl,imx6q-ipu", .data
= &ipu_type_imx6q
, },
738 MODULE_DEVICE_TABLE(of
, imx_ipu_dt_ids
);
740 static int ipu_submodules_init(struct ipu_soc
*ipu
,
741 struct platform_device
*pdev
, unsigned long ipu_base
,
746 struct device
*dev
= &pdev
->dev
;
747 const struct ipu_devtype
*devtype
= ipu
->devtype
;
749 ret
= ipu_di_init(ipu
, dev
, 0, ipu_base
+ devtype
->disp0_ofs
,
750 IPU_CONF_DI0_EN
, ipu_clk
);
756 ret
= ipu_di_init(ipu
, dev
, 1, ipu_base
+ devtype
->disp1_ofs
,
757 IPU_CONF_DI1_EN
, ipu_clk
);
763 ret
= ipu_dc_init(ipu
, dev
, ipu_base
+ devtype
->cm_ofs
+
764 IPU_CM_DC_REG_OFS
, ipu_base
+ devtype
->dc_tmpl_ofs
);
766 unit
= "dc_template";
770 ret
= ipu_dmfc_init(ipu
, dev
, ipu_base
+
771 devtype
->cm_ofs
+ IPU_CM_DMFC_REG_OFS
, ipu_clk
);
777 ret
= ipu_dp_init(ipu
, dev
, ipu_base
+ devtype
->srm_ofs
);
794 dev_err(&pdev
->dev
, "init %s failed with %d\n", unit
, ret
);
798 static void ipu_irq_handle(struct ipu_soc
*ipu
, const int *regs
, int num_regs
)
800 unsigned long status
;
801 int i
, bit
, irq_base
;
803 for (i
= 0; i
< num_regs
; i
++) {
805 status
= ipu_cm_read(ipu
, IPU_INT_STAT(regs
[i
]));
806 status
&= ipu_cm_read(ipu
, IPU_INT_CTRL(regs
[i
]));
808 irq_base
= ipu
->irq_start
+ regs
[i
] * 32;
809 for_each_set_bit(bit
, &status
, 32)
810 generic_handle_irq(irq_base
+ bit
);
814 static void ipu_irq_handler(unsigned int irq
, struct irq_desc
*desc
)
816 struct ipu_soc
*ipu
= irq_desc_get_handler_data(desc
);
817 const int int_reg
[] = { 0, 1, 2, 3, 10, 11, 12, 13, 14};
818 struct irq_chip
*chip
= irq_get_chip(irq
);
820 chained_irq_enter(chip
, desc
);
822 ipu_irq_handle(ipu
, int_reg
, ARRAY_SIZE(int_reg
));
824 chained_irq_exit(chip
, desc
);
827 static void ipu_err_irq_handler(unsigned int irq
, struct irq_desc
*desc
)
829 struct ipu_soc
*ipu
= irq_desc_get_handler_data(desc
);
830 const int int_reg
[] = { 4, 5, 8, 9};
831 struct irq_chip
*chip
= irq_get_chip(irq
);
833 chained_irq_enter(chip
, desc
);
835 ipu_irq_handle(ipu
, int_reg
, ARRAY_SIZE(int_reg
));
837 chained_irq_exit(chip
, desc
);
840 static void ipu_ack_irq(struct irq_data
*d
)
842 struct ipu_soc
*ipu
= irq_data_get_irq_chip_data(d
);
843 unsigned int irq
= d
->irq
- ipu
->irq_start
;
845 ipu_cm_write(ipu
, 1 << (irq
% 32), IPU_INT_STAT(irq
/ 32));
848 static void ipu_unmask_irq(struct irq_data
*d
)
850 struct ipu_soc
*ipu
= irq_data_get_irq_chip_data(d
);
851 unsigned int irq
= d
->irq
- ipu
->irq_start
;
855 spin_lock_irqsave(&ipu
->lock
, flags
);
857 reg
= ipu_cm_read(ipu
, IPU_INT_CTRL(irq
/ 32));
858 reg
|= 1 << (irq
% 32);
859 ipu_cm_write(ipu
, reg
, IPU_INT_CTRL(irq
/ 32));
861 spin_unlock_irqrestore(&ipu
->lock
, flags
);
864 static void ipu_mask_irq(struct irq_data
*d
)
866 struct ipu_soc
*ipu
= irq_data_get_irq_chip_data(d
);
867 unsigned int irq
= d
->irq
- ipu
->irq_start
;
871 spin_lock_irqsave(&ipu
->lock
, flags
);
873 reg
= ipu_cm_read(ipu
, IPU_INT_CTRL(irq
/ 32));
874 reg
&= ~(1 << (irq
% 32));
875 ipu_cm_write(ipu
, reg
, IPU_INT_CTRL(irq
/ 32));
877 spin_unlock_irqrestore(&ipu
->lock
, flags
);
880 static struct irq_chip ipu_irq_chip
= {
882 .irq_ack
= ipu_ack_irq
,
883 .irq_mask
= ipu_mask_irq
,
884 .irq_unmask
= ipu_unmask_irq
,
887 int ipu_idmac_channel_irq(struct ipu_soc
*ipu
, struct ipuv3_channel
*channel
,
888 enum ipu_channel_irq irq_type
)
890 return ipu
->irq_start
+ irq_type
+ channel
->num
;
892 EXPORT_SYMBOL_GPL(ipu_idmac_channel_irq
);
894 static void ipu_submodules_exit(struct ipu_soc
*ipu
)
903 static int platform_remove_devices_fn(struct device
*dev
, void *unused
)
905 struct platform_device
*pdev
= to_platform_device(dev
);
907 platform_device_unregister(pdev
);
912 static void platform_device_unregister_children(struct platform_device
*pdev
)
914 device_for_each_child(&pdev
->dev
, NULL
, platform_remove_devices_fn
);
917 struct ipu_platform_reg
{
918 struct ipu_client_platformdata pdata
;
922 static const struct ipu_platform_reg client_reg
[] = {
927 .dp
= IPU_DP_FLOW_SYNC_BG
,
928 .dma
[0] = IPUV3_CHANNEL_MEM_BG_SYNC
,
931 .name
= "imx-ipuv3-crtc",
937 .dma
[0] = IPUV3_CHANNEL_MEM_DC_SYNC
,
940 .name
= "imx-ipuv3-crtc",
944 static int ipu_client_id
;
946 static int ipu_add_subdevice_pdata(struct device
*dev
,
947 const struct ipu_platform_reg
*reg
)
949 struct platform_device
*pdev
;
951 pdev
= platform_device_register_data(dev
, reg
->name
, ipu_client_id
++,
952 ®
->pdata
, sizeof(struct ipu_platform_reg
));
954 return pdev
? 0 : -EINVAL
;
957 static int ipu_add_client_devices(struct ipu_soc
*ipu
)
962 for (i
= 0; i
< ARRAY_SIZE(client_reg
); i
++) {
963 const struct ipu_platform_reg
*reg
= &client_reg
[i
];
964 ret
= ipu_add_subdevice_pdata(ipu
->dev
, reg
);
972 platform_device_unregister_children(to_platform_device(ipu
->dev
));
977 static int ipu_irq_init(struct ipu_soc
*ipu
)
981 ipu
->irq_start
= irq_alloc_descs(-1, 0, IPU_NUM_IRQS
, 0);
982 if (ipu
->irq_start
< 0)
983 return ipu
->irq_start
;
985 for (i
= ipu
->irq_start
; i
< ipu
->irq_start
+ IPU_NUM_IRQS
; i
++) {
986 irq_set_chip_and_handler(i
, &ipu_irq_chip
, handle_level_irq
);
987 set_irq_flags(i
, IRQF_VALID
);
988 irq_set_chip_data(i
, ipu
);
991 irq_set_chained_handler(ipu
->irq_sync
, ipu_irq_handler
);
992 irq_set_handler_data(ipu
->irq_sync
, ipu
);
993 irq_set_chained_handler(ipu
->irq_err
, ipu_err_irq_handler
);
994 irq_set_handler_data(ipu
->irq_err
, ipu
);
999 static void ipu_irq_exit(struct ipu_soc
*ipu
)
1003 irq_set_chained_handler(ipu
->irq_err
, NULL
);
1004 irq_set_handler_data(ipu
->irq_err
, NULL
);
1005 irq_set_chained_handler(ipu
->irq_sync
, NULL
);
1006 irq_set_handler_data(ipu
->irq_sync
, NULL
);
1008 for (i
= ipu
->irq_start
; i
< ipu
->irq_start
+ IPU_NUM_IRQS
; i
++) {
1009 set_irq_flags(i
, 0);
1010 irq_set_chip(i
, NULL
);
1011 irq_set_chip_data(i
, NULL
);
1014 irq_free_descs(ipu
->irq_start
, IPU_NUM_IRQS
);
1017 static int ipu_probe(struct platform_device
*pdev
)
1019 const struct of_device_id
*of_id
=
1020 of_match_device(imx_ipu_dt_ids
, &pdev
->dev
);
1021 struct ipu_soc
*ipu
;
1022 struct resource
*res
;
1023 unsigned long ipu_base
;
1024 int i
, ret
, irq_sync
, irq_err
;
1025 const struct ipu_devtype
*devtype
;
1027 devtype
= of_id
->data
;
1029 irq_sync
= platform_get_irq(pdev
, 0);
1030 irq_err
= platform_get_irq(pdev
, 1);
1031 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
1033 dev_dbg(&pdev
->dev
, "irq_sync: %d irq_err: %d\n",
1036 if (!res
|| irq_sync
< 0 || irq_err
< 0)
1039 ipu_base
= res
->start
;
1041 ipu
= devm_kzalloc(&pdev
->dev
, sizeof(*ipu
), GFP_KERNEL
);
1045 for (i
= 0; i
< 64; i
++)
1046 ipu
->channel
[i
].ipu
= ipu
;
1047 ipu
->devtype
= devtype
;
1048 ipu
->ipu_type
= devtype
->type
;
1050 spin_lock_init(&ipu
->lock
);
1051 mutex_init(&ipu
->channel_lock
);
1053 dev_dbg(&pdev
->dev
, "cm_reg: 0x%08lx\n",
1054 ipu_base
+ devtype
->cm_ofs
);
1055 dev_dbg(&pdev
->dev
, "idmac: 0x%08lx\n",
1056 ipu_base
+ devtype
->cm_ofs
+ IPU_CM_IDMAC_REG_OFS
);
1057 dev_dbg(&pdev
->dev
, "cpmem: 0x%08lx\n",
1058 ipu_base
+ devtype
->cpmem_ofs
);
1059 dev_dbg(&pdev
->dev
, "disp0: 0x%08lx\n",
1060 ipu_base
+ devtype
->disp0_ofs
);
1061 dev_dbg(&pdev
->dev
, "disp1: 0x%08lx\n",
1062 ipu_base
+ devtype
->disp1_ofs
);
1063 dev_dbg(&pdev
->dev
, "srm: 0x%08lx\n",
1064 ipu_base
+ devtype
->srm_ofs
);
1065 dev_dbg(&pdev
->dev
, "tpm: 0x%08lx\n",
1066 ipu_base
+ devtype
->tpm_ofs
);
1067 dev_dbg(&pdev
->dev
, "dc: 0x%08lx\n",
1068 ipu_base
+ devtype
->cm_ofs
+ IPU_CM_DC_REG_OFS
);
1069 dev_dbg(&pdev
->dev
, "ic: 0x%08lx\n",
1070 ipu_base
+ devtype
->cm_ofs
+ IPU_CM_IC_REG_OFS
);
1071 dev_dbg(&pdev
->dev
, "dmfc: 0x%08lx\n",
1072 ipu_base
+ devtype
->cm_ofs
+ IPU_CM_DMFC_REG_OFS
);
1073 dev_dbg(&pdev
->dev
, "vdi: 0x%08lx\n",
1074 ipu_base
+ devtype
->vdi_ofs
);
1076 ipu
->cm_reg
= devm_ioremap(&pdev
->dev
,
1077 ipu_base
+ devtype
->cm_ofs
, PAGE_SIZE
);
1078 ipu
->idmac_reg
= devm_ioremap(&pdev
->dev
,
1079 ipu_base
+ devtype
->cm_ofs
+ IPU_CM_IDMAC_REG_OFS
,
1081 ipu
->cpmem_base
= devm_ioremap(&pdev
->dev
,
1082 ipu_base
+ devtype
->cpmem_ofs
, PAGE_SIZE
);
1084 if (!ipu
->cm_reg
|| !ipu
->idmac_reg
|| !ipu
->cpmem_base
) {
1086 goto failed_ioremap
;
1089 ipu
->clk
= devm_clk_get(&pdev
->dev
, "bus");
1090 if (IS_ERR(ipu
->clk
)) {
1091 ret
= PTR_ERR(ipu
->clk
);
1092 dev_err(&pdev
->dev
, "clk_get failed with %d", ret
);
1093 goto failed_clk_get
;
1096 platform_set_drvdata(pdev
, ipu
);
1098 clk_prepare_enable(ipu
->clk
);
1100 ipu
->dev
= &pdev
->dev
;
1101 ipu
->irq_sync
= irq_sync
;
1102 ipu
->irq_err
= irq_err
;
1104 ret
= ipu_irq_init(ipu
);
1106 goto out_failed_irq
;
1108 ret
= ipu_reset(ipu
);
1110 goto out_failed_reset
;
1112 /* Set MCU_T to divide MCU access window into 2 */
1113 ipu_cm_write(ipu
, 0x00400000L
| (IPU_MCU_T_DEFAULT
<< 18),
1116 ret
= ipu_submodules_init(ipu
, pdev
, ipu_base
, ipu
->clk
);
1118 goto failed_submodules_init
;
1120 ret
= ipu_add_client_devices(ipu
);
1122 dev_err(&pdev
->dev
, "adding client devices failed with %d\n",
1124 goto failed_add_clients
;
1127 dev_info(&pdev
->dev
, "%s probed\n", devtype
->name
);
1132 ipu_submodules_exit(ipu
);
1133 failed_submodules_init
:
1137 clk_disable_unprepare(ipu
->clk
);
1143 static int ipu_remove(struct platform_device
*pdev
)
1145 struct ipu_soc
*ipu
= platform_get_drvdata(pdev
);
1147 platform_device_unregister_children(pdev
);
1148 ipu_submodules_exit(ipu
);
1151 clk_disable_unprepare(ipu
->clk
);
1156 static struct platform_driver imx_ipu_driver
= {
1158 .name
= "imx-ipuv3",
1159 .of_match_table
= imx_ipu_dt_ids
,
1162 .remove
= ipu_remove
,
1165 module_platform_driver(imx_ipu_driver
);
1167 MODULE_DESCRIPTION("i.MX IPU v3 driver");
1168 MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>");
1169 MODULE_LICENSE("GPL");