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/reset.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/irqdomain.h>
30 #include <linux/of_device.h>
32 #include <drm/drm_fourcc.h>
34 #include "imx-ipu-v3.h"
37 static inline u32
ipu_cm_read(struct ipu_soc
*ipu
, unsigned offset
)
39 return readl(ipu
->cm_reg
+ offset
);
42 static inline void ipu_cm_write(struct ipu_soc
*ipu
, u32 value
, unsigned offset
)
44 writel(value
, ipu
->cm_reg
+ offset
);
47 static inline u32
ipu_idmac_read(struct ipu_soc
*ipu
, unsigned offset
)
49 return readl(ipu
->idmac_reg
+ offset
);
52 static inline void ipu_idmac_write(struct ipu_soc
*ipu
, u32 value
,
55 writel(value
, ipu
->idmac_reg
+ offset
);
58 void ipu_srm_dp_sync_update(struct ipu_soc
*ipu
)
62 val
= ipu_cm_read(ipu
, IPU_SRM_PRI2
);
64 ipu_cm_write(ipu
, val
, IPU_SRM_PRI2
);
66 EXPORT_SYMBOL_GPL(ipu_srm_dp_sync_update
);
68 struct ipu_ch_param __iomem
*ipu_get_cpmem(struct ipuv3_channel
*channel
)
70 struct ipu_soc
*ipu
= channel
->ipu
;
72 return ipu
->cpmem_base
+ channel
->num
;
74 EXPORT_SYMBOL_GPL(ipu_get_cpmem
);
76 void ipu_cpmem_set_high_priority(struct ipuv3_channel
*channel
)
78 struct ipu_soc
*ipu
= channel
->ipu
;
79 struct ipu_ch_param __iomem
*p
= ipu_get_cpmem(channel
);
82 if (ipu
->ipu_type
== IPUV3EX
)
83 ipu_ch_param_write_field(p
, IPU_FIELD_ID
, 1);
85 val
= ipu_idmac_read(ipu
, IDMAC_CHA_PRI(channel
->num
));
86 val
|= 1 << (channel
->num
% 32);
87 ipu_idmac_write(ipu
, val
, IDMAC_CHA_PRI(channel
->num
));
89 EXPORT_SYMBOL_GPL(ipu_cpmem_set_high_priority
);
91 void ipu_ch_param_write_field(struct ipu_ch_param __iomem
*base
, u32 wbs
, u32 v
)
93 u32 bit
= (wbs
>> 8) % 160;
94 u32 size
= wbs
& 0xff;
95 u32 word
= (wbs
>> 8) / 160;
98 u32 mask
= (1 << size
) - 1;
101 pr_debug("%s %d %d %d\n", __func__
, word
, bit
, size
);
103 val
= readl(&base
->word
[word
].data
[i
]);
104 val
&= ~(mask
<< ofs
);
106 writel(val
, &base
->word
[word
].data
[i
]);
108 if ((bit
+ size
- 1) / 32 > i
) {
109 val
= readl(&base
->word
[word
].data
[i
+ 1]);
110 val
&= ~(mask
>> (ofs
? (32 - ofs
) : 0));
111 val
|= v
>> (ofs
? (32 - ofs
) : 0);
112 writel(val
, &base
->word
[word
].data
[i
+ 1]);
115 EXPORT_SYMBOL_GPL(ipu_ch_param_write_field
);
117 u32
ipu_ch_param_read_field(struct ipu_ch_param __iomem
*base
, u32 wbs
)
119 u32 bit
= (wbs
>> 8) % 160;
120 u32 size
= wbs
& 0xff;
121 u32 word
= (wbs
>> 8) / 160;
124 u32 mask
= (1 << size
) - 1;
127 pr_debug("%s %d %d %d\n", __func__
, word
, bit
, size
);
129 val
= (readl(&base
->word
[word
].data
[i
]) >> ofs
) & mask
;
131 if ((bit
+ size
- 1) / 32 > i
) {
133 tmp
= readl(&base
->word
[word
].data
[i
+ 1]);
134 tmp
&= mask
>> (ofs
? (32 - ofs
) : 0);
135 val
|= tmp
<< (ofs
? (32 - ofs
) : 0);
140 EXPORT_SYMBOL_GPL(ipu_ch_param_read_field
);
142 int ipu_cpmem_set_format_rgb(struct ipu_ch_param __iomem
*p
,
143 const struct ipu_rgb
*rgb
)
145 int bpp
= 0, npb
= 0, ro
, go
, bo
, to
;
147 ro
= rgb
->bits_per_pixel
- rgb
->red
.length
- rgb
->red
.offset
;
148 go
= rgb
->bits_per_pixel
- rgb
->green
.length
- rgb
->green
.offset
;
149 bo
= rgb
->bits_per_pixel
- rgb
->blue
.length
- rgb
->blue
.offset
;
150 to
= rgb
->bits_per_pixel
- rgb
->transp
.length
- rgb
->transp
.offset
;
152 ipu_ch_param_write_field(p
, IPU_FIELD_WID0
, rgb
->red
.length
- 1);
153 ipu_ch_param_write_field(p
, IPU_FIELD_OFS0
, ro
);
154 ipu_ch_param_write_field(p
, IPU_FIELD_WID1
, rgb
->green
.length
- 1);
155 ipu_ch_param_write_field(p
, IPU_FIELD_OFS1
, go
);
156 ipu_ch_param_write_field(p
, IPU_FIELD_WID2
, rgb
->blue
.length
- 1);
157 ipu_ch_param_write_field(p
, IPU_FIELD_OFS2
, bo
);
159 if (rgb
->transp
.length
) {
160 ipu_ch_param_write_field(p
, IPU_FIELD_WID3
,
161 rgb
->transp
.length
- 1);
162 ipu_ch_param_write_field(p
, IPU_FIELD_OFS3
, to
);
164 ipu_ch_param_write_field(p
, IPU_FIELD_WID3
, 7);
165 ipu_ch_param_write_field(p
, IPU_FIELD_OFS3
,
166 rgb
->bits_per_pixel
);
169 switch (rgb
->bits_per_pixel
) {
189 ipu_ch_param_write_field(p
, IPU_FIELD_BPP
, bpp
);
190 ipu_ch_param_write_field(p
, IPU_FIELD_NPB
, npb
);
191 ipu_ch_param_write_field(p
, IPU_FIELD_PFS
, 7); /* rgb mode */
195 EXPORT_SYMBOL_GPL(ipu_cpmem_set_format_rgb
);
197 int ipu_cpmem_set_format_passthrough(struct ipu_ch_param __iomem
*p
,
200 int bpp
= 0, npb
= 0;
223 ipu_ch_param_write_field(p
, IPU_FIELD_BPP
, bpp
);
224 ipu_ch_param_write_field(p
, IPU_FIELD_NPB
, npb
);
225 ipu_ch_param_write_field(p
, IPU_FIELD_PFS
, 6); /* raw mode */
229 EXPORT_SYMBOL_GPL(ipu_cpmem_set_format_passthrough
);
231 void ipu_cpmem_set_yuv_interleaved(struct ipu_ch_param __iomem
*p
,
234 switch (pixel_format
) {
235 case V4L2_PIX_FMT_UYVY
:
236 ipu_ch_param_write_field(p
, IPU_FIELD_BPP
, 3); /* bits/pixel */
237 ipu_ch_param_write_field(p
, IPU_FIELD_PFS
, 0xA); /* pix format */
238 ipu_ch_param_write_field(p
, IPU_FIELD_NPB
, 31); /* burst size */
240 case V4L2_PIX_FMT_YUYV
:
241 ipu_ch_param_write_field(p
, IPU_FIELD_BPP
, 3); /* bits/pixel */
242 ipu_ch_param_write_field(p
, IPU_FIELD_PFS
, 0x8); /* pix format */
243 ipu_ch_param_write_field(p
, IPU_FIELD_NPB
, 31); /* burst size */
247 EXPORT_SYMBOL_GPL(ipu_cpmem_set_yuv_interleaved
);
249 void ipu_cpmem_set_yuv_planar_full(struct ipu_ch_param __iomem
*p
,
250 u32 pixel_format
, int stride
, int u_offset
, int v_offset
)
252 switch (pixel_format
) {
253 case V4L2_PIX_FMT_YUV420
:
254 ipu_ch_param_write_field(p
, IPU_FIELD_SLUV
, (stride
/ 2) - 1);
255 ipu_ch_param_write_field(p
, IPU_FIELD_UBO
, u_offset
/ 8);
256 ipu_ch_param_write_field(p
, IPU_FIELD_VBO
, v_offset
/ 8);
258 case V4L2_PIX_FMT_YVU420
:
259 ipu_ch_param_write_field(p
, IPU_FIELD_SLUV
, (stride
/ 2) - 1);
260 ipu_ch_param_write_field(p
, IPU_FIELD_UBO
, v_offset
/ 8);
261 ipu_ch_param_write_field(p
, IPU_FIELD_VBO
, u_offset
/ 8);
265 EXPORT_SYMBOL_GPL(ipu_cpmem_set_yuv_planar_full
);
267 void ipu_cpmem_set_yuv_planar(struct ipu_ch_param __iomem
*p
, u32 pixel_format
,
268 int stride
, int height
)
270 int u_offset
, v_offset
;
273 switch (pixel_format
) {
274 case V4L2_PIX_FMT_YUV420
:
275 case V4L2_PIX_FMT_YVU420
:
276 uv_stride
= stride
/ 2;
277 u_offset
= stride
* height
;
278 v_offset
= u_offset
+ (uv_stride
* height
/ 2);
279 ipu_cpmem_set_yuv_planar_full(p
, pixel_format
, stride
,
284 EXPORT_SYMBOL_GPL(ipu_cpmem_set_yuv_planar
);
286 static const struct ipu_rgb def_rgb_32
= {
287 .red
= { .offset
= 16, .length
= 8, },
288 .green
= { .offset
= 8, .length
= 8, },
289 .blue
= { .offset
= 0, .length
= 8, },
290 .transp
= { .offset
= 24, .length
= 8, },
291 .bits_per_pixel
= 32,
294 static const struct ipu_rgb def_bgr_32
= {
295 .red
= { .offset
= 0, .length
= 8, },
296 .green
= { .offset
= 8, .length
= 8, },
297 .blue
= { .offset
= 16, .length
= 8, },
298 .transp
= { .offset
= 24, .length
= 8, },
299 .bits_per_pixel
= 32,
302 static const struct ipu_rgb def_rgb_24
= {
303 .red
= { .offset
= 16, .length
= 8, },
304 .green
= { .offset
= 8, .length
= 8, },
305 .blue
= { .offset
= 0, .length
= 8, },
306 .transp
= { .offset
= 0, .length
= 0, },
307 .bits_per_pixel
= 24,
310 static const struct ipu_rgb def_bgr_24
= {
311 .red
= { .offset
= 0, .length
= 8, },
312 .green
= { .offset
= 8, .length
= 8, },
313 .blue
= { .offset
= 16, .length
= 8, },
314 .transp
= { .offset
= 0, .length
= 0, },
315 .bits_per_pixel
= 24,
318 static const struct ipu_rgb def_rgb_16
= {
319 .red
= { .offset
= 11, .length
= 5, },
320 .green
= { .offset
= 5, .length
= 6, },
321 .blue
= { .offset
= 0, .length
= 5, },
322 .transp
= { .offset
= 0, .length
= 0, },
323 .bits_per_pixel
= 16,
326 static const struct ipu_rgb def_bgr_16
= {
327 .red
= { .offset
= 0, .length
= 5, },
328 .green
= { .offset
= 5, .length
= 6, },
329 .blue
= { .offset
= 11, .length
= 5, },
330 .transp
= { .offset
= 0, .length
= 0, },
331 .bits_per_pixel
= 16,
334 #define Y_OFFSET(pix, x, y) ((x) + pix->width * (y))
335 #define U_OFFSET(pix, x, y) ((pix->width * pix->height) + \
336 (pix->width * (y) / 4) + (x) / 2)
337 #define V_OFFSET(pix, x, y) ((pix->width * pix->height) + \
338 (pix->width * pix->height / 4) + \
339 (pix->width * (y) / 4) + (x) / 2)
341 int ipu_cpmem_set_fmt(struct ipu_ch_param __iomem
*cpmem
, u32 drm_fourcc
)
343 switch (drm_fourcc
) {
344 case DRM_FORMAT_YUV420
:
345 case DRM_FORMAT_YVU420
:
347 ipu_ch_param_write_field(cpmem
, IPU_FIELD_PFS
, 2);
349 ipu_ch_param_write_field(cpmem
, IPU_FIELD_NPB
, 63);
351 case DRM_FORMAT_UYVY
:
353 ipu_ch_param_write_field(cpmem
, IPU_FIELD_BPP
, 3);
355 ipu_ch_param_write_field(cpmem
, IPU_FIELD_PFS
, 0xA);
357 ipu_ch_param_write_field(cpmem
, IPU_FIELD_NPB
, 31);
359 case DRM_FORMAT_YUYV
:
361 ipu_ch_param_write_field(cpmem
, IPU_FIELD_BPP
, 3);
363 ipu_ch_param_write_field(cpmem
, IPU_FIELD_PFS
, 0x8);
365 ipu_ch_param_write_field(cpmem
, IPU_FIELD_NPB
, 31);
367 case DRM_FORMAT_ABGR8888
:
368 case DRM_FORMAT_XBGR8888
:
369 ipu_cpmem_set_format_rgb(cpmem
, &def_bgr_32
);
371 case DRM_FORMAT_ARGB8888
:
372 case DRM_FORMAT_XRGB8888
:
373 ipu_cpmem_set_format_rgb(cpmem
, &def_rgb_32
);
375 case DRM_FORMAT_BGR888
:
376 ipu_cpmem_set_format_rgb(cpmem
, &def_bgr_24
);
378 case DRM_FORMAT_RGB888
:
379 ipu_cpmem_set_format_rgb(cpmem
, &def_rgb_24
);
381 case DRM_FORMAT_RGB565
:
382 ipu_cpmem_set_format_rgb(cpmem
, &def_rgb_16
);
384 case DRM_FORMAT_BGR565
:
385 ipu_cpmem_set_format_rgb(cpmem
, &def_bgr_16
);
393 EXPORT_SYMBOL_GPL(ipu_cpmem_set_fmt
);
396 * The V4L2 spec defines packed RGB formats in memory byte order, which from
397 * point of view of the IPU corresponds to little-endian words with the first
398 * component in the least significant bits.
399 * The DRM pixel formats and IPU internal representation are ordered the other
400 * way around, with the first named component ordered at the most significant
401 * bits. Further, V4L2 formats are not well defined:
402 * http://linuxtv.org/downloads/v4l-dvb-apis/packed-rgb.html
403 * We choose the interpretation which matches GStreamer behavior.
405 static int v4l2_pix_fmt_to_drm_fourcc(u32 pixelformat
)
407 switch (pixelformat
) {
408 case V4L2_PIX_FMT_RGB565
:
410 * Here we choose the 'corrected' interpretation of RGBP, a
411 * little-endian 16-bit word with the red component at the most
413 * g[2:0]b[4:0] r[4:0]g[5:3] <=> [16:0] R:G:B
415 return DRM_FORMAT_RGB565
;
416 case V4L2_PIX_FMT_BGR24
:
417 /* B G R <=> [24:0] R:G:B */
418 return DRM_FORMAT_RGB888
;
419 case V4L2_PIX_FMT_RGB24
:
420 /* R G B <=> [24:0] B:G:R */
421 return DRM_FORMAT_BGR888
;
422 case V4L2_PIX_FMT_BGR32
:
423 /* B G R A <=> [32:0] A:B:G:R */
424 return DRM_FORMAT_XRGB8888
;
425 case V4L2_PIX_FMT_RGB32
:
426 /* R G B A <=> [32:0] A:B:G:R */
427 return DRM_FORMAT_XBGR8888
;
428 case V4L2_PIX_FMT_UYVY
:
429 return DRM_FORMAT_UYVY
;
430 case V4L2_PIX_FMT_YUYV
:
431 return DRM_FORMAT_YUYV
;
432 case V4L2_PIX_FMT_YUV420
:
433 return DRM_FORMAT_YUV420
;
434 case V4L2_PIX_FMT_YVU420
:
435 return DRM_FORMAT_YVU420
;
441 enum ipu_color_space
ipu_drm_fourcc_to_colorspace(u32 drm_fourcc
)
443 switch (drm_fourcc
) {
444 case DRM_FORMAT_RGB565
:
445 case DRM_FORMAT_BGR565
:
446 case DRM_FORMAT_RGB888
:
447 case DRM_FORMAT_BGR888
:
448 case DRM_FORMAT_XRGB8888
:
449 case DRM_FORMAT_XBGR8888
:
450 case DRM_FORMAT_RGBX8888
:
451 case DRM_FORMAT_BGRX8888
:
452 case DRM_FORMAT_ARGB8888
:
453 case DRM_FORMAT_ABGR8888
:
454 case DRM_FORMAT_RGBA8888
:
455 case DRM_FORMAT_BGRA8888
:
456 return IPUV3_COLORSPACE_RGB
;
457 case DRM_FORMAT_YUYV
:
458 case DRM_FORMAT_UYVY
:
459 case DRM_FORMAT_YUV420
:
460 case DRM_FORMAT_YVU420
:
461 return IPUV3_COLORSPACE_YUV
;
463 return IPUV3_COLORSPACE_UNKNOWN
;
466 EXPORT_SYMBOL_GPL(ipu_drm_fourcc_to_colorspace
);
468 int ipu_cpmem_set_image(struct ipu_ch_param __iomem
*cpmem
,
469 struct ipu_image
*image
)
471 struct v4l2_pix_format
*pix
= &image
->pix
;
472 int y_offset
, u_offset
, v_offset
;
474 pr_debug("%s: resolution: %dx%d stride: %d\n",
475 __func__
, pix
->width
, pix
->height
,
478 ipu_cpmem_set_resolution(cpmem
, image
->rect
.width
,
480 ipu_cpmem_set_stride(cpmem
, pix
->bytesperline
);
482 ipu_cpmem_set_fmt(cpmem
, v4l2_pix_fmt_to_drm_fourcc(pix
->pixelformat
));
484 switch (pix
->pixelformat
) {
485 case V4L2_PIX_FMT_YUV420
:
486 case V4L2_PIX_FMT_YVU420
:
487 y_offset
= Y_OFFSET(pix
, image
->rect
.left
, image
->rect
.top
);
488 u_offset
= U_OFFSET(pix
, image
->rect
.left
,
489 image
->rect
.top
) - y_offset
;
490 v_offset
= V_OFFSET(pix
, image
->rect
.left
,
491 image
->rect
.top
) - y_offset
;
493 ipu_cpmem_set_yuv_planar_full(cpmem
, pix
->pixelformat
,
494 pix
->bytesperline
, u_offset
, v_offset
);
495 ipu_cpmem_set_buffer(cpmem
, 0, image
->phys
+ y_offset
);
497 case V4L2_PIX_FMT_UYVY
:
498 case V4L2_PIX_FMT_YUYV
:
499 ipu_cpmem_set_buffer(cpmem
, 0, image
->phys
+
500 image
->rect
.left
* 2 +
501 image
->rect
.top
* image
->pix
.bytesperline
);
503 case V4L2_PIX_FMT_RGB32
:
504 case V4L2_PIX_FMT_BGR32
:
505 ipu_cpmem_set_buffer(cpmem
, 0, image
->phys
+
506 image
->rect
.left
* 4 +
507 image
->rect
.top
* image
->pix
.bytesperline
);
509 case V4L2_PIX_FMT_RGB565
:
510 ipu_cpmem_set_buffer(cpmem
, 0, image
->phys
+
511 image
->rect
.left
* 2 +
512 image
->rect
.top
* image
->pix
.bytesperline
);
514 case V4L2_PIX_FMT_RGB24
:
515 case V4L2_PIX_FMT_BGR24
:
516 ipu_cpmem_set_buffer(cpmem
, 0, image
->phys
+
517 image
->rect
.left
* 3 +
518 image
->rect
.top
* image
->pix
.bytesperline
);
526 EXPORT_SYMBOL_GPL(ipu_cpmem_set_image
);
528 enum ipu_color_space
ipu_pixelformat_to_colorspace(u32 pixelformat
)
530 switch (pixelformat
) {
531 case V4L2_PIX_FMT_YUV420
:
532 case V4L2_PIX_FMT_YVU420
:
533 case V4L2_PIX_FMT_UYVY
:
534 case V4L2_PIX_FMT_YUYV
:
535 return IPUV3_COLORSPACE_YUV
;
536 case V4L2_PIX_FMT_RGB32
:
537 case V4L2_PIX_FMT_BGR32
:
538 case V4L2_PIX_FMT_RGB24
:
539 case V4L2_PIX_FMT_BGR24
:
540 case V4L2_PIX_FMT_RGB565
:
541 return IPUV3_COLORSPACE_RGB
;
543 return IPUV3_COLORSPACE_UNKNOWN
;
546 EXPORT_SYMBOL_GPL(ipu_pixelformat_to_colorspace
);
548 struct ipuv3_channel
*ipu_idmac_get(struct ipu_soc
*ipu
, unsigned num
)
550 struct ipuv3_channel
*channel
;
552 dev_dbg(ipu
->dev
, "%s %d\n", __func__
, num
);
555 return ERR_PTR(-ENODEV
);
557 mutex_lock(&ipu
->channel_lock
);
559 channel
= &ipu
->channel
[num
];
562 channel
= ERR_PTR(-EBUSY
);
566 channel
->busy
= true;
570 mutex_unlock(&ipu
->channel_lock
);
574 EXPORT_SYMBOL_GPL(ipu_idmac_get
);
576 void ipu_idmac_put(struct ipuv3_channel
*channel
)
578 struct ipu_soc
*ipu
= channel
->ipu
;
580 dev_dbg(ipu
->dev
, "%s %d\n", __func__
, channel
->num
);
582 mutex_lock(&ipu
->channel_lock
);
584 channel
->busy
= false;
586 mutex_unlock(&ipu
->channel_lock
);
588 EXPORT_SYMBOL_GPL(ipu_idmac_put
);
590 #define idma_mask(ch) (1 << (ch & 0x1f))
592 void ipu_idmac_set_double_buffer(struct ipuv3_channel
*channel
,
595 struct ipu_soc
*ipu
= channel
->ipu
;
599 spin_lock_irqsave(&ipu
->lock
, flags
);
601 reg
= ipu_cm_read(ipu
, IPU_CHA_DB_MODE_SEL(channel
->num
));
603 reg
|= idma_mask(channel
->num
);
605 reg
&= ~idma_mask(channel
->num
);
606 ipu_cm_write(ipu
, reg
, IPU_CHA_DB_MODE_SEL(channel
->num
));
608 spin_unlock_irqrestore(&ipu
->lock
, flags
);
610 EXPORT_SYMBOL_GPL(ipu_idmac_set_double_buffer
);
612 int ipu_module_enable(struct ipu_soc
*ipu
, u32 mask
)
614 unsigned long lock_flags
;
617 spin_lock_irqsave(&ipu
->lock
, lock_flags
);
619 val
= ipu_cm_read(ipu
, IPU_DISP_GEN
);
621 if (mask
& IPU_CONF_DI0_EN
)
622 val
|= IPU_DI0_COUNTER_RELEASE
;
623 if (mask
& IPU_CONF_DI1_EN
)
624 val
|= IPU_DI1_COUNTER_RELEASE
;
626 ipu_cm_write(ipu
, val
, IPU_DISP_GEN
);
628 val
= ipu_cm_read(ipu
, IPU_CONF
);
630 ipu_cm_write(ipu
, val
, IPU_CONF
);
632 spin_unlock_irqrestore(&ipu
->lock
, lock_flags
);
636 EXPORT_SYMBOL_GPL(ipu_module_enable
);
638 int ipu_module_disable(struct ipu_soc
*ipu
, u32 mask
)
640 unsigned long lock_flags
;
643 spin_lock_irqsave(&ipu
->lock
, lock_flags
);
645 val
= ipu_cm_read(ipu
, IPU_CONF
);
647 ipu_cm_write(ipu
, val
, IPU_CONF
);
649 val
= ipu_cm_read(ipu
, IPU_DISP_GEN
);
651 if (mask
& IPU_CONF_DI0_EN
)
652 val
&= ~IPU_DI0_COUNTER_RELEASE
;
653 if (mask
& IPU_CONF_DI1_EN
)
654 val
&= ~IPU_DI1_COUNTER_RELEASE
;
656 ipu_cm_write(ipu
, val
, IPU_DISP_GEN
);
658 spin_unlock_irqrestore(&ipu
->lock
, lock_flags
);
662 EXPORT_SYMBOL_GPL(ipu_module_disable
);
664 void ipu_idmac_select_buffer(struct ipuv3_channel
*channel
, u32 buf_num
)
666 struct ipu_soc
*ipu
= channel
->ipu
;
667 unsigned int chno
= channel
->num
;
670 spin_lock_irqsave(&ipu
->lock
, flags
);
672 /* Mark buffer as ready. */
674 ipu_cm_write(ipu
, idma_mask(chno
), IPU_CHA_BUF0_RDY(chno
));
676 ipu_cm_write(ipu
, idma_mask(chno
), IPU_CHA_BUF1_RDY(chno
));
678 spin_unlock_irqrestore(&ipu
->lock
, flags
);
680 EXPORT_SYMBOL_GPL(ipu_idmac_select_buffer
);
682 int ipu_idmac_enable_channel(struct ipuv3_channel
*channel
)
684 struct ipu_soc
*ipu
= channel
->ipu
;
688 spin_lock_irqsave(&ipu
->lock
, flags
);
690 val
= ipu_idmac_read(ipu
, IDMAC_CHA_EN(channel
->num
));
691 val
|= idma_mask(channel
->num
);
692 ipu_idmac_write(ipu
, val
, IDMAC_CHA_EN(channel
->num
));
694 spin_unlock_irqrestore(&ipu
->lock
, flags
);
698 EXPORT_SYMBOL_GPL(ipu_idmac_enable_channel
);
700 int ipu_idmac_wait_busy(struct ipuv3_channel
*channel
, int ms
)
702 struct ipu_soc
*ipu
= channel
->ipu
;
703 unsigned long timeout
;
705 timeout
= jiffies
+ msecs_to_jiffies(ms
);
706 while (ipu_idmac_read(ipu
, IDMAC_CHA_BUSY(channel
->num
)) &
707 idma_mask(channel
->num
)) {
708 if (time_after(jiffies
, timeout
))
715 EXPORT_SYMBOL_GPL(ipu_idmac_wait_busy
);
717 int ipu_idmac_disable_channel(struct ipuv3_channel
*channel
)
719 struct ipu_soc
*ipu
= channel
->ipu
;
723 spin_lock_irqsave(&ipu
->lock
, flags
);
725 /* Disable DMA channel(s) */
726 val
= ipu_idmac_read(ipu
, IDMAC_CHA_EN(channel
->num
));
727 val
&= ~idma_mask(channel
->num
);
728 ipu_idmac_write(ipu
, val
, IDMAC_CHA_EN(channel
->num
));
730 /* Set channel buffers NOT to be ready */
731 ipu_cm_write(ipu
, 0xf0000000, IPU_GPR
); /* write one to clear */
733 if (ipu_cm_read(ipu
, IPU_CHA_BUF0_RDY(channel
->num
)) &
734 idma_mask(channel
->num
)) {
735 ipu_cm_write(ipu
, idma_mask(channel
->num
),
736 IPU_CHA_BUF0_RDY(channel
->num
));
739 if (ipu_cm_read(ipu
, IPU_CHA_BUF1_RDY(channel
->num
)) &
740 idma_mask(channel
->num
)) {
741 ipu_cm_write(ipu
, idma_mask(channel
->num
),
742 IPU_CHA_BUF1_RDY(channel
->num
));
745 ipu_cm_write(ipu
, 0x0, IPU_GPR
); /* write one to set */
747 /* Reset the double buffer */
748 val
= ipu_cm_read(ipu
, IPU_CHA_DB_MODE_SEL(channel
->num
));
749 val
&= ~idma_mask(channel
->num
);
750 ipu_cm_write(ipu
, val
, IPU_CHA_DB_MODE_SEL(channel
->num
));
752 spin_unlock_irqrestore(&ipu
->lock
, flags
);
756 EXPORT_SYMBOL_GPL(ipu_idmac_disable_channel
);
758 static int ipu_memory_reset(struct ipu_soc
*ipu
)
760 unsigned long timeout
;
762 ipu_cm_write(ipu
, 0x807FFFFF, IPU_MEM_RST
);
764 timeout
= jiffies
+ msecs_to_jiffies(1000);
765 while (ipu_cm_read(ipu
, IPU_MEM_RST
) & 0x80000000) {
766 if (time_after(jiffies
, timeout
))
776 unsigned long cm_ofs
;
777 unsigned long cpmem_ofs
;
778 unsigned long srm_ofs
;
779 unsigned long tpm_ofs
;
780 unsigned long disp0_ofs
;
781 unsigned long disp1_ofs
;
782 unsigned long dc_tmpl_ofs
;
783 unsigned long vdi_ofs
;
784 enum ipuv3_type type
;
787 static struct ipu_devtype ipu_type_imx51
= {
789 .cm_ofs
= 0x1e000000,
790 .cpmem_ofs
= 0x1f000000,
791 .srm_ofs
= 0x1f040000,
792 .tpm_ofs
= 0x1f060000,
793 .disp0_ofs
= 0x1e040000,
794 .disp1_ofs
= 0x1e048000,
795 .dc_tmpl_ofs
= 0x1f080000,
796 .vdi_ofs
= 0x1e068000,
800 static struct ipu_devtype ipu_type_imx53
= {
802 .cm_ofs
= 0x06000000,
803 .cpmem_ofs
= 0x07000000,
804 .srm_ofs
= 0x07040000,
805 .tpm_ofs
= 0x07060000,
806 .disp0_ofs
= 0x06040000,
807 .disp1_ofs
= 0x06048000,
808 .dc_tmpl_ofs
= 0x07080000,
809 .vdi_ofs
= 0x06068000,
813 static struct ipu_devtype ipu_type_imx6q
= {
815 .cm_ofs
= 0x00200000,
816 .cpmem_ofs
= 0x00300000,
817 .srm_ofs
= 0x00340000,
818 .tpm_ofs
= 0x00360000,
819 .disp0_ofs
= 0x00240000,
820 .disp1_ofs
= 0x00248000,
821 .dc_tmpl_ofs
= 0x00380000,
822 .vdi_ofs
= 0x00268000,
826 static const struct of_device_id imx_ipu_dt_ids
[] = {
827 { .compatible
= "fsl,imx51-ipu", .data
= &ipu_type_imx51
, },
828 { .compatible
= "fsl,imx53-ipu", .data
= &ipu_type_imx53
, },
829 { .compatible
= "fsl,imx6q-ipu", .data
= &ipu_type_imx6q
, },
832 MODULE_DEVICE_TABLE(of
, imx_ipu_dt_ids
);
834 static int ipu_submodules_init(struct ipu_soc
*ipu
,
835 struct platform_device
*pdev
, unsigned long ipu_base
,
840 struct device
*dev
= &pdev
->dev
;
841 const struct ipu_devtype
*devtype
= ipu
->devtype
;
843 ret
= ipu_di_init(ipu
, dev
, 0, ipu_base
+ devtype
->disp0_ofs
,
844 IPU_CONF_DI0_EN
, ipu_clk
);
850 ret
= ipu_di_init(ipu
, dev
, 1, ipu_base
+ devtype
->disp1_ofs
,
851 IPU_CONF_DI1_EN
, ipu_clk
);
857 ret
= ipu_dc_init(ipu
, dev
, ipu_base
+ devtype
->cm_ofs
+
858 IPU_CM_DC_REG_OFS
, ipu_base
+ devtype
->dc_tmpl_ofs
);
860 unit
= "dc_template";
864 ret
= ipu_dmfc_init(ipu
, dev
, ipu_base
+
865 devtype
->cm_ofs
+ IPU_CM_DMFC_REG_OFS
, ipu_clk
);
871 ret
= ipu_dp_init(ipu
, dev
, ipu_base
+ devtype
->srm_ofs
);
888 dev_err(&pdev
->dev
, "init %s failed with %d\n", unit
, ret
);
892 static void ipu_irq_handle(struct ipu_soc
*ipu
, const int *regs
, int num_regs
)
894 unsigned long status
;
897 for (i
= 0; i
< num_regs
; i
++) {
899 status
= ipu_cm_read(ipu
, IPU_INT_STAT(regs
[i
]));
900 status
&= ipu_cm_read(ipu
, IPU_INT_CTRL(regs
[i
]));
902 for_each_set_bit(bit
, &status
, 32) {
903 irq
= irq_linear_revmap(ipu
->domain
, regs
[i
] * 32 + bit
);
905 generic_handle_irq(irq
);
910 static void ipu_irq_handler(unsigned int irq
, struct irq_desc
*desc
)
912 struct ipu_soc
*ipu
= irq_desc_get_handler_data(desc
);
913 const int int_reg
[] = { 0, 1, 2, 3, 10, 11, 12, 13, 14};
914 struct irq_chip
*chip
= irq_get_chip(irq
);
916 chained_irq_enter(chip
, desc
);
918 ipu_irq_handle(ipu
, int_reg
, ARRAY_SIZE(int_reg
));
920 chained_irq_exit(chip
, desc
);
923 static void ipu_err_irq_handler(unsigned int irq
, struct irq_desc
*desc
)
925 struct ipu_soc
*ipu
= irq_desc_get_handler_data(desc
);
926 const int int_reg
[] = { 4, 5, 8, 9};
927 struct irq_chip
*chip
= irq_get_chip(irq
);
929 chained_irq_enter(chip
, desc
);
931 ipu_irq_handle(ipu
, int_reg
, ARRAY_SIZE(int_reg
));
933 chained_irq_exit(chip
, desc
);
936 int ipu_idmac_channel_irq(struct ipu_soc
*ipu
, struct ipuv3_channel
*channel
,
937 enum ipu_channel_irq irq_type
)
939 int irq
= irq_linear_revmap(ipu
->domain
, irq_type
+ channel
->num
);
942 irq
= irq_create_mapping(ipu
->domain
, irq_type
+ channel
->num
);
946 EXPORT_SYMBOL_GPL(ipu_idmac_channel_irq
);
948 static void ipu_submodules_exit(struct ipu_soc
*ipu
)
957 static int platform_remove_devices_fn(struct device
*dev
, void *unused
)
959 struct platform_device
*pdev
= to_platform_device(dev
);
961 platform_device_unregister(pdev
);
966 static void platform_device_unregister_children(struct platform_device
*pdev
)
968 device_for_each_child(&pdev
->dev
, NULL
, platform_remove_devices_fn
);
971 struct ipu_platform_reg
{
972 struct ipu_client_platformdata pdata
;
976 static const struct ipu_platform_reg client_reg
[] = {
981 .dp
= IPU_DP_FLOW_SYNC_BG
,
982 .dma
[0] = IPUV3_CHANNEL_MEM_BG_SYNC
,
983 .dma
[1] = IPUV3_CHANNEL_MEM_FG_SYNC
,
985 .name
= "imx-ipuv3-crtc",
991 .dma
[0] = IPUV3_CHANNEL_MEM_DC_SYNC
,
994 .name
= "imx-ipuv3-crtc",
998 static int ipu_client_id
;
1000 static int ipu_add_subdevice_pdata(struct device
*dev
,
1001 const struct ipu_platform_reg
*reg
)
1003 struct platform_device
*pdev
;
1005 pdev
= platform_device_register_data(dev
, reg
->name
, ipu_client_id
++,
1006 ®
->pdata
, sizeof(struct ipu_platform_reg
));
1008 return PTR_ERR_OR_ZERO(pdev
);
1011 static int ipu_add_client_devices(struct ipu_soc
*ipu
)
1016 for (i
= 0; i
< ARRAY_SIZE(client_reg
); i
++) {
1017 const struct ipu_platform_reg
*reg
= &client_reg
[i
];
1018 ret
= ipu_add_subdevice_pdata(ipu
->dev
, reg
);
1026 platform_device_unregister_children(to_platform_device(ipu
->dev
));
1032 static int ipu_irq_init(struct ipu_soc
*ipu
)
1034 struct irq_chip_generic
*gc
;
1035 struct irq_chip_type
*ct
;
1036 unsigned long unused
[IPU_NUM_IRQS
/ 32] = {
1037 0x400100d0, 0xffe000fd,
1038 0x400100d0, 0xffe000fd,
1039 0x400100d0, 0xffe000fd,
1040 0x4077ffff, 0xffe7e1fd,
1041 0x23fffffe, 0x8880fff0,
1042 0xf98fe7d0, 0xfff81fff,
1043 0x400100d0, 0xffe000fd,
1048 ipu
->domain
= irq_domain_add_linear(ipu
->dev
->of_node
, IPU_NUM_IRQS
,
1049 &irq_generic_chip_ops
, ipu
);
1051 dev_err(ipu
->dev
, "failed to add irq domain\n");
1055 ret
= irq_alloc_domain_generic_chips(ipu
->domain
, 32, 1, "IPU",
1056 handle_level_irq
, 0, IRQF_VALID
, 0);
1058 dev_err(ipu
->dev
, "failed to alloc generic irq chips\n");
1059 irq_domain_remove(ipu
->domain
);
1063 for (i
= 0; i
< IPU_NUM_IRQS
; i
+= 32) {
1064 gc
= irq_get_domain_generic_chip(ipu
->domain
, i
);
1065 gc
->reg_base
= ipu
->cm_reg
;
1066 gc
->unused
= unused
[i
/ 32];
1067 ct
= gc
->chip_types
;
1068 ct
->chip
.irq_ack
= irq_gc_ack_set_bit
;
1069 ct
->chip
.irq_mask
= irq_gc_mask_clr_bit
;
1070 ct
->chip
.irq_unmask
= irq_gc_mask_set_bit
;
1071 ct
->regs
.ack
= IPU_INT_STAT(i
/ 32);
1072 ct
->regs
.mask
= IPU_INT_CTRL(i
/ 32);
1075 irq_set_chained_handler(ipu
->irq_sync
, ipu_irq_handler
);
1076 irq_set_handler_data(ipu
->irq_sync
, ipu
);
1077 irq_set_chained_handler(ipu
->irq_err
, ipu_err_irq_handler
);
1078 irq_set_handler_data(ipu
->irq_err
, ipu
);
1083 static void ipu_irq_exit(struct ipu_soc
*ipu
)
1087 irq_set_chained_handler(ipu
->irq_err
, NULL
);
1088 irq_set_handler_data(ipu
->irq_err
, NULL
);
1089 irq_set_chained_handler(ipu
->irq_sync
, NULL
);
1090 irq_set_handler_data(ipu
->irq_sync
, NULL
);
1092 /* TODO: remove irq_domain_generic_chips */
1094 for (i
= 0; i
< IPU_NUM_IRQS
; i
++) {
1095 irq
= irq_linear_revmap(ipu
->domain
, i
);
1097 irq_dispose_mapping(irq
);
1100 irq_domain_remove(ipu
->domain
);
1103 static int ipu_probe(struct platform_device
*pdev
)
1105 const struct of_device_id
*of_id
=
1106 of_match_device(imx_ipu_dt_ids
, &pdev
->dev
);
1107 struct ipu_soc
*ipu
;
1108 struct resource
*res
;
1109 unsigned long ipu_base
;
1110 int i
, ret
, irq_sync
, irq_err
;
1111 const struct ipu_devtype
*devtype
;
1113 devtype
= of_id
->data
;
1115 irq_sync
= platform_get_irq(pdev
, 0);
1116 irq_err
= platform_get_irq(pdev
, 1);
1117 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
1119 dev_dbg(&pdev
->dev
, "irq_sync: %d irq_err: %d\n",
1122 if (!res
|| irq_sync
< 0 || irq_err
< 0)
1125 ipu_base
= res
->start
;
1127 ipu
= devm_kzalloc(&pdev
->dev
, sizeof(*ipu
), GFP_KERNEL
);
1131 for (i
= 0; i
< 64; i
++)
1132 ipu
->channel
[i
].ipu
= ipu
;
1133 ipu
->devtype
= devtype
;
1134 ipu
->ipu_type
= devtype
->type
;
1136 spin_lock_init(&ipu
->lock
);
1137 mutex_init(&ipu
->channel_lock
);
1139 dev_dbg(&pdev
->dev
, "cm_reg: 0x%08lx\n",
1140 ipu_base
+ devtype
->cm_ofs
);
1141 dev_dbg(&pdev
->dev
, "idmac: 0x%08lx\n",
1142 ipu_base
+ devtype
->cm_ofs
+ IPU_CM_IDMAC_REG_OFS
);
1143 dev_dbg(&pdev
->dev
, "cpmem: 0x%08lx\n",
1144 ipu_base
+ devtype
->cpmem_ofs
);
1145 dev_dbg(&pdev
->dev
, "disp0: 0x%08lx\n",
1146 ipu_base
+ devtype
->disp0_ofs
);
1147 dev_dbg(&pdev
->dev
, "disp1: 0x%08lx\n",
1148 ipu_base
+ devtype
->disp1_ofs
);
1149 dev_dbg(&pdev
->dev
, "srm: 0x%08lx\n",
1150 ipu_base
+ devtype
->srm_ofs
);
1151 dev_dbg(&pdev
->dev
, "tpm: 0x%08lx\n",
1152 ipu_base
+ devtype
->tpm_ofs
);
1153 dev_dbg(&pdev
->dev
, "dc: 0x%08lx\n",
1154 ipu_base
+ devtype
->cm_ofs
+ IPU_CM_DC_REG_OFS
);
1155 dev_dbg(&pdev
->dev
, "ic: 0x%08lx\n",
1156 ipu_base
+ devtype
->cm_ofs
+ IPU_CM_IC_REG_OFS
);
1157 dev_dbg(&pdev
->dev
, "dmfc: 0x%08lx\n",
1158 ipu_base
+ devtype
->cm_ofs
+ IPU_CM_DMFC_REG_OFS
);
1159 dev_dbg(&pdev
->dev
, "vdi: 0x%08lx\n",
1160 ipu_base
+ devtype
->vdi_ofs
);
1162 ipu
->cm_reg
= devm_ioremap(&pdev
->dev
,
1163 ipu_base
+ devtype
->cm_ofs
, PAGE_SIZE
);
1164 ipu
->idmac_reg
= devm_ioremap(&pdev
->dev
,
1165 ipu_base
+ devtype
->cm_ofs
+ IPU_CM_IDMAC_REG_OFS
,
1167 ipu
->cpmem_base
= devm_ioremap(&pdev
->dev
,
1168 ipu_base
+ devtype
->cpmem_ofs
, PAGE_SIZE
);
1170 if (!ipu
->cm_reg
|| !ipu
->idmac_reg
|| !ipu
->cpmem_base
)
1173 ipu
->clk
= devm_clk_get(&pdev
->dev
, "bus");
1174 if (IS_ERR(ipu
->clk
)) {
1175 ret
= PTR_ERR(ipu
->clk
);
1176 dev_err(&pdev
->dev
, "clk_get failed with %d", ret
);
1180 platform_set_drvdata(pdev
, ipu
);
1182 ret
= clk_prepare_enable(ipu
->clk
);
1184 dev_err(&pdev
->dev
, "clk_prepare_enable failed: %d\n", ret
);
1188 ipu
->dev
= &pdev
->dev
;
1189 ipu
->irq_sync
= irq_sync
;
1190 ipu
->irq_err
= irq_err
;
1192 ret
= ipu_irq_init(ipu
);
1194 goto out_failed_irq
;
1196 ret
= device_reset(&pdev
->dev
);
1198 dev_err(&pdev
->dev
, "failed to reset: %d\n", ret
);
1199 goto out_failed_reset
;
1201 ret
= ipu_memory_reset(ipu
);
1203 goto out_failed_reset
;
1205 /* Set MCU_T to divide MCU access window into 2 */
1206 ipu_cm_write(ipu
, 0x00400000L
| (IPU_MCU_T_DEFAULT
<< 18),
1209 ret
= ipu_submodules_init(ipu
, pdev
, ipu_base
, ipu
->clk
);
1211 goto failed_submodules_init
;
1213 ret
= ipu_add_client_devices(ipu
);
1215 dev_err(&pdev
->dev
, "adding client devices failed with %d\n",
1217 goto failed_add_clients
;
1220 dev_info(&pdev
->dev
, "%s probed\n", devtype
->name
);
1225 ipu_submodules_exit(ipu
);
1226 failed_submodules_init
:
1230 clk_disable_unprepare(ipu
->clk
);
1234 static int ipu_remove(struct platform_device
*pdev
)
1236 struct ipu_soc
*ipu
= platform_get_drvdata(pdev
);
1238 platform_device_unregister_children(pdev
);
1239 ipu_submodules_exit(ipu
);
1242 clk_disable_unprepare(ipu
->clk
);
1247 static struct platform_driver imx_ipu_driver
= {
1249 .name
= "imx-ipuv3",
1250 .of_match_table
= imx_ipu_dt_ids
,
1253 .remove
= ipu_remove
,
1256 module_platform_driver(imx_ipu_driver
);
1258 MODULE_ALIAS("platform:imx-ipuv3");
1259 MODULE_DESCRIPTION("i.MX IPU v3 driver");
1260 MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>");
1261 MODULE_LICENSE("GPL");