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/reset.h>
20 #include <linux/platform_device.h>
21 #include <linux/err.h>
22 #include <linux/spinlock.h>
23 #include <linux/delay.h>
24 #include <linux/interrupt.h>
26 #include <linux/clk.h>
27 #include <linux/list.h>
28 #include <linux/irq.h>
29 #include <linux/irqchip/chained_irq.h>
30 #include <linux/of_device.h>
32 #include "imx-ipu-v3.h"
35 static inline u32
ipu_cm_read(struct ipu_soc
*ipu
, unsigned offset
)
37 return readl(ipu
->cm_reg
+ offset
);
40 static inline void ipu_cm_write(struct ipu_soc
*ipu
, u32 value
, unsigned offset
)
42 writel(value
, ipu
->cm_reg
+ offset
);
45 static inline u32
ipu_idmac_read(struct ipu_soc
*ipu
, unsigned offset
)
47 return readl(ipu
->idmac_reg
+ offset
);
50 static inline void ipu_idmac_write(struct ipu_soc
*ipu
, u32 value
,
53 writel(value
, ipu
->idmac_reg
+ offset
);
56 void ipu_srm_dp_sync_update(struct ipu_soc
*ipu
)
60 val
= ipu_cm_read(ipu
, IPU_SRM_PRI2
);
62 ipu_cm_write(ipu
, val
, IPU_SRM_PRI2
);
64 EXPORT_SYMBOL_GPL(ipu_srm_dp_sync_update
);
66 struct ipu_ch_param __iomem
*ipu_get_cpmem(struct ipuv3_channel
*channel
)
68 struct ipu_soc
*ipu
= channel
->ipu
;
70 return ipu
->cpmem_base
+ channel
->num
;
72 EXPORT_SYMBOL_GPL(ipu_get_cpmem
);
74 void ipu_cpmem_set_high_priority(struct ipuv3_channel
*channel
)
76 struct ipu_soc
*ipu
= channel
->ipu
;
77 struct ipu_ch_param __iomem
*p
= ipu_get_cpmem(channel
);
80 if (ipu
->ipu_type
== IPUV3EX
)
81 ipu_ch_param_write_field(p
, IPU_FIELD_ID
, 1);
83 val
= ipu_idmac_read(ipu
, IDMAC_CHA_PRI(channel
->num
));
84 val
|= 1 << (channel
->num
% 32);
85 ipu_idmac_write(ipu
, val
, IDMAC_CHA_PRI(channel
->num
));
87 EXPORT_SYMBOL_GPL(ipu_cpmem_set_high_priority
);
89 void ipu_ch_param_write_field(struct ipu_ch_param __iomem
*base
, u32 wbs
, u32 v
)
91 u32 bit
= (wbs
>> 8) % 160;
92 u32 size
= wbs
& 0xff;
93 u32 word
= (wbs
>> 8) / 160;
96 u32 mask
= (1 << size
) - 1;
99 pr_debug("%s %d %d %d\n", __func__
, word
, bit
, size
);
101 val
= readl(&base
->word
[word
].data
[i
]);
102 val
&= ~(mask
<< ofs
);
104 writel(val
, &base
->word
[word
].data
[i
]);
106 if ((bit
+ size
- 1) / 32 > i
) {
107 val
= readl(&base
->word
[word
].data
[i
+ 1]);
108 val
&= ~(mask
>> (ofs
? (32 - ofs
) : 0));
109 val
|= v
>> (ofs
? (32 - ofs
) : 0);
110 writel(val
, &base
->word
[word
].data
[i
+ 1]);
113 EXPORT_SYMBOL_GPL(ipu_ch_param_write_field
);
115 u32
ipu_ch_param_read_field(struct ipu_ch_param __iomem
*base
, u32 wbs
)
117 u32 bit
= (wbs
>> 8) % 160;
118 u32 size
= wbs
& 0xff;
119 u32 word
= (wbs
>> 8) / 160;
122 u32 mask
= (1 << size
) - 1;
125 pr_debug("%s %d %d %d\n", __func__
, word
, bit
, size
);
127 val
= (readl(&base
->word
[word
].data
[i
]) >> ofs
) & mask
;
129 if ((bit
+ size
- 1) / 32 > i
) {
131 tmp
= readl(&base
->word
[word
].data
[i
+ 1]);
132 tmp
&= mask
>> (ofs
? (32 - ofs
) : 0);
133 val
|= tmp
<< (ofs
? (32 - ofs
) : 0);
138 EXPORT_SYMBOL_GPL(ipu_ch_param_read_field
);
140 int ipu_cpmem_set_format_rgb(struct ipu_ch_param __iomem
*p
,
143 int bpp
= 0, npb
= 0, ro
, go
, bo
, to
;
145 ro
= rgb
->bits_per_pixel
- rgb
->red
.length
- rgb
->red
.offset
;
146 go
= rgb
->bits_per_pixel
- rgb
->green
.length
- rgb
->green
.offset
;
147 bo
= rgb
->bits_per_pixel
- rgb
->blue
.length
- rgb
->blue
.offset
;
148 to
= rgb
->bits_per_pixel
- rgb
->transp
.length
- rgb
->transp
.offset
;
150 ipu_ch_param_write_field(p
, IPU_FIELD_WID0
, rgb
->red
.length
- 1);
151 ipu_ch_param_write_field(p
, IPU_FIELD_OFS0
, ro
);
152 ipu_ch_param_write_field(p
, IPU_FIELD_WID1
, rgb
->green
.length
- 1);
153 ipu_ch_param_write_field(p
, IPU_FIELD_OFS1
, go
);
154 ipu_ch_param_write_field(p
, IPU_FIELD_WID2
, rgb
->blue
.length
- 1);
155 ipu_ch_param_write_field(p
, IPU_FIELD_OFS2
, bo
);
157 if (rgb
->transp
.length
) {
158 ipu_ch_param_write_field(p
, IPU_FIELD_WID3
,
159 rgb
->transp
.length
- 1);
160 ipu_ch_param_write_field(p
, IPU_FIELD_OFS3
, to
);
162 ipu_ch_param_write_field(p
, IPU_FIELD_WID3
, 7);
163 ipu_ch_param_write_field(p
, IPU_FIELD_OFS3
,
164 rgb
->bits_per_pixel
);
167 switch (rgb
->bits_per_pixel
) {
187 ipu_ch_param_write_field(p
, IPU_FIELD_BPP
, bpp
);
188 ipu_ch_param_write_field(p
, IPU_FIELD_NPB
, npb
);
189 ipu_ch_param_write_field(p
, IPU_FIELD_PFS
, 7); /* rgb mode */
193 EXPORT_SYMBOL_GPL(ipu_cpmem_set_format_rgb
);
195 int ipu_cpmem_set_format_passthrough(struct ipu_ch_param __iomem
*p
,
198 int bpp
= 0, npb
= 0;
221 ipu_ch_param_write_field(p
, IPU_FIELD_BPP
, bpp
);
222 ipu_ch_param_write_field(p
, IPU_FIELD_NPB
, npb
);
223 ipu_ch_param_write_field(p
, IPU_FIELD_PFS
, 6); /* raw mode */
227 EXPORT_SYMBOL_GPL(ipu_cpmem_set_format_passthrough
);
229 void ipu_cpmem_set_yuv_interleaved(struct ipu_ch_param __iomem
*p
,
232 switch (pixel_format
) {
233 case V4L2_PIX_FMT_UYVY
:
234 ipu_ch_param_write_field(p
, IPU_FIELD_BPP
, 3); /* bits/pixel */
235 ipu_ch_param_write_field(p
, IPU_FIELD_PFS
, 0xA); /* pix format */
236 ipu_ch_param_write_field(p
, IPU_FIELD_NPB
, 31); /* burst size */
238 case V4L2_PIX_FMT_YUYV
:
239 ipu_ch_param_write_field(p
, IPU_FIELD_BPP
, 3); /* bits/pixel */
240 ipu_ch_param_write_field(p
, IPU_FIELD_PFS
, 0x8); /* pix format */
241 ipu_ch_param_write_field(p
, IPU_FIELD_NPB
, 31); /* burst size */
245 EXPORT_SYMBOL_GPL(ipu_cpmem_set_yuv_interleaved
);
247 void ipu_cpmem_set_yuv_planar_full(struct ipu_ch_param __iomem
*p
,
248 u32 pixel_format
, int stride
, int u_offset
, int v_offset
)
250 switch (pixel_format
) {
251 case V4L2_PIX_FMT_YUV420
:
252 ipu_ch_param_write_field(p
, IPU_FIELD_SLUV
, (stride
/ 2) - 1);
253 ipu_ch_param_write_field(p
, IPU_FIELD_UBO
, u_offset
/ 8);
254 ipu_ch_param_write_field(p
, IPU_FIELD_VBO
, v_offset
/ 8);
256 case V4L2_PIX_FMT_YVU420
:
257 ipu_ch_param_write_field(p
, IPU_FIELD_SLUV
, (stride
/ 2) - 1);
258 ipu_ch_param_write_field(p
, IPU_FIELD_UBO
, v_offset
/ 8);
259 ipu_ch_param_write_field(p
, IPU_FIELD_VBO
, u_offset
/ 8);
263 EXPORT_SYMBOL_GPL(ipu_cpmem_set_yuv_planar_full
);
265 void ipu_cpmem_set_yuv_planar(struct ipu_ch_param __iomem
*p
, u32 pixel_format
,
266 int stride
, int height
)
268 int u_offset
, v_offset
;
271 switch (pixel_format
) {
272 case V4L2_PIX_FMT_YUV420
:
273 case V4L2_PIX_FMT_YVU420
:
274 uv_stride
= stride
/ 2;
275 u_offset
= stride
* height
;
276 v_offset
= u_offset
+ (uv_stride
* height
/ 2);
277 ipu_cpmem_set_yuv_planar_full(p
, pixel_format
, stride
,
282 EXPORT_SYMBOL_GPL(ipu_cpmem_set_yuv_planar
);
284 static struct ipu_rgb def_rgb_32
= {
285 .red
= { .offset
= 16, .length
= 8, },
286 .green
= { .offset
= 8, .length
= 8, },
287 .blue
= { .offset
= 0, .length
= 8, },
288 .transp
= { .offset
= 24, .length
= 8, },
289 .bits_per_pixel
= 32,
292 static struct ipu_rgb def_bgr_32
= {
293 .red
= { .offset
= 16, .length
= 8, },
294 .green
= { .offset
= 8, .length
= 8, },
295 .blue
= { .offset
= 0, .length
= 8, },
296 .transp
= { .offset
= 24, .length
= 8, },
297 .bits_per_pixel
= 32,
300 static struct ipu_rgb def_rgb_24
= {
301 .red
= { .offset
= 0, .length
= 8, },
302 .green
= { .offset
= 8, .length
= 8, },
303 .blue
= { .offset
= 16, .length
= 8, },
304 .transp
= { .offset
= 0, .length
= 0, },
305 .bits_per_pixel
= 24,
308 static struct ipu_rgb def_bgr_24
= {
309 .red
= { .offset
= 16, .length
= 8, },
310 .green
= { .offset
= 8, .length
= 8, },
311 .blue
= { .offset
= 0, .length
= 8, },
312 .transp
= { .offset
= 0, .length
= 0, },
313 .bits_per_pixel
= 24,
316 static struct ipu_rgb def_rgb_16
= {
317 .red
= { .offset
= 11, .length
= 5, },
318 .green
= { .offset
= 5, .length
= 6, },
319 .blue
= { .offset
= 0, .length
= 5, },
320 .transp
= { .offset
= 0, .length
= 0, },
321 .bits_per_pixel
= 16,
324 #define Y_OFFSET(pix, x, y) ((x) + pix->width * (y))
325 #define U_OFFSET(pix, x, y) ((pix->width * pix->height) + \
326 (pix->width * (y) / 4) + (x) / 2)
327 #define V_OFFSET(pix, x, y) ((pix->width * pix->height) + \
328 (pix->width * pix->height / 4) + \
329 (pix->width * (y) / 4) + (x) / 2)
331 int ipu_cpmem_set_fmt(struct ipu_ch_param __iomem
*cpmem
, u32 pixelformat
)
333 switch (pixelformat
) {
334 case V4L2_PIX_FMT_YUV420
:
335 case V4L2_PIX_FMT_YVU420
:
337 ipu_ch_param_write_field(cpmem
, IPU_FIELD_PFS
, 2);
339 ipu_ch_param_write_field(cpmem
, IPU_FIELD_NPB
, 63);
341 case V4L2_PIX_FMT_UYVY
:
343 ipu_ch_param_write_field(cpmem
, IPU_FIELD_BPP
, 3);
345 ipu_ch_param_write_field(cpmem
, IPU_FIELD_PFS
, 0xA);
347 ipu_ch_param_write_field(cpmem
, IPU_FIELD_NPB
, 31);
349 case V4L2_PIX_FMT_YUYV
:
351 ipu_ch_param_write_field(cpmem
, IPU_FIELD_BPP
, 3);
353 ipu_ch_param_write_field(cpmem
, IPU_FIELD_PFS
, 0x8);
355 ipu_ch_param_write_field(cpmem
, IPU_FIELD_NPB
, 31);
357 case V4L2_PIX_FMT_RGB32
:
358 ipu_cpmem_set_format_rgb(cpmem
, &def_rgb_32
);
360 case V4L2_PIX_FMT_RGB565
:
361 ipu_cpmem_set_format_rgb(cpmem
, &def_rgb_16
);
363 case V4L2_PIX_FMT_BGR32
:
364 ipu_cpmem_set_format_rgb(cpmem
, &def_bgr_32
);
366 case V4L2_PIX_FMT_RGB24
:
367 ipu_cpmem_set_format_rgb(cpmem
, &def_rgb_24
);
369 case V4L2_PIX_FMT_BGR24
:
370 ipu_cpmem_set_format_rgb(cpmem
, &def_bgr_24
);
378 EXPORT_SYMBOL_GPL(ipu_cpmem_set_fmt
);
380 int ipu_cpmem_set_image(struct ipu_ch_param __iomem
*cpmem
,
381 struct ipu_image
*image
)
383 struct v4l2_pix_format
*pix
= &image
->pix
;
384 int y_offset
, u_offset
, v_offset
;
386 pr_debug("%s: resolution: %dx%d stride: %d\n",
387 __func__
, pix
->width
, pix
->height
,
390 ipu_cpmem_set_resolution(cpmem
, image
->rect
.width
,
392 ipu_cpmem_set_stride(cpmem
, pix
->bytesperline
);
394 ipu_cpmem_set_fmt(cpmem
, pix
->pixelformat
);
396 switch (pix
->pixelformat
) {
397 case V4L2_PIX_FMT_YUV420
:
398 case V4L2_PIX_FMT_YVU420
:
399 y_offset
= Y_OFFSET(pix
, image
->rect
.left
, image
->rect
.top
);
400 u_offset
= U_OFFSET(pix
, image
->rect
.left
,
401 image
->rect
.top
) - y_offset
;
402 v_offset
= V_OFFSET(pix
, image
->rect
.left
,
403 image
->rect
.top
) - y_offset
;
405 ipu_cpmem_set_yuv_planar_full(cpmem
, pix
->pixelformat
,
406 pix
->bytesperline
, u_offset
, v_offset
);
407 ipu_cpmem_set_buffer(cpmem
, 0, image
->phys
+ y_offset
);
409 case V4L2_PIX_FMT_UYVY
:
410 case V4L2_PIX_FMT_YUYV
:
411 ipu_cpmem_set_buffer(cpmem
, 0, image
->phys
+
412 image
->rect
.left
* 2 +
413 image
->rect
.top
* image
->pix
.bytesperline
);
415 case V4L2_PIX_FMT_RGB32
:
416 case V4L2_PIX_FMT_BGR32
:
417 ipu_cpmem_set_buffer(cpmem
, 0, image
->phys
+
418 image
->rect
.left
* 4 +
419 image
->rect
.top
* image
->pix
.bytesperline
);
421 case V4L2_PIX_FMT_RGB565
:
422 ipu_cpmem_set_buffer(cpmem
, 0, image
->phys
+
423 image
->rect
.left
* 2 +
424 image
->rect
.top
* image
->pix
.bytesperline
);
426 case V4L2_PIX_FMT_RGB24
:
427 case V4L2_PIX_FMT_BGR24
:
428 ipu_cpmem_set_buffer(cpmem
, 0, image
->phys
+
429 image
->rect
.left
* 3 +
430 image
->rect
.top
* image
->pix
.bytesperline
);
438 EXPORT_SYMBOL_GPL(ipu_cpmem_set_image
);
440 enum ipu_color_space
ipu_pixelformat_to_colorspace(u32 pixelformat
)
442 switch (pixelformat
) {
443 case V4L2_PIX_FMT_YUV420
:
444 case V4L2_PIX_FMT_YVU420
:
445 case V4L2_PIX_FMT_UYVY
:
446 case V4L2_PIX_FMT_YUYV
:
447 return IPUV3_COLORSPACE_YUV
;
448 case V4L2_PIX_FMT_RGB32
:
449 case V4L2_PIX_FMT_BGR32
:
450 case V4L2_PIX_FMT_RGB24
:
451 case V4L2_PIX_FMT_BGR24
:
452 case V4L2_PIX_FMT_RGB565
:
453 return IPUV3_COLORSPACE_RGB
;
455 return IPUV3_COLORSPACE_UNKNOWN
;
458 EXPORT_SYMBOL_GPL(ipu_pixelformat_to_colorspace
);
460 struct ipuv3_channel
*ipu_idmac_get(struct ipu_soc
*ipu
, unsigned num
)
462 struct ipuv3_channel
*channel
;
464 dev_dbg(ipu
->dev
, "%s %d\n", __func__
, num
);
467 return ERR_PTR(-ENODEV
);
469 mutex_lock(&ipu
->channel_lock
);
471 channel
= &ipu
->channel
[num
];
474 channel
= ERR_PTR(-EBUSY
);
482 mutex_unlock(&ipu
->channel_lock
);
486 EXPORT_SYMBOL_GPL(ipu_idmac_get
);
488 void ipu_idmac_put(struct ipuv3_channel
*channel
)
490 struct ipu_soc
*ipu
= channel
->ipu
;
492 dev_dbg(ipu
->dev
, "%s %d\n", __func__
, channel
->num
);
494 mutex_lock(&ipu
->channel_lock
);
498 mutex_unlock(&ipu
->channel_lock
);
500 EXPORT_SYMBOL_GPL(ipu_idmac_put
);
502 #define idma_mask(ch) (1 << (ch & 0x1f))
504 void ipu_idmac_set_double_buffer(struct ipuv3_channel
*channel
,
507 struct ipu_soc
*ipu
= channel
->ipu
;
511 spin_lock_irqsave(&ipu
->lock
, flags
);
513 reg
= ipu_cm_read(ipu
, IPU_CHA_DB_MODE_SEL(channel
->num
));
515 reg
|= idma_mask(channel
->num
);
517 reg
&= ~idma_mask(channel
->num
);
518 ipu_cm_write(ipu
, reg
, IPU_CHA_DB_MODE_SEL(channel
->num
));
520 spin_unlock_irqrestore(&ipu
->lock
, flags
);
522 EXPORT_SYMBOL_GPL(ipu_idmac_set_double_buffer
);
524 int ipu_module_enable(struct ipu_soc
*ipu
, u32 mask
)
526 unsigned long lock_flags
;
529 spin_lock_irqsave(&ipu
->lock
, lock_flags
);
531 val
= ipu_cm_read(ipu
, IPU_DISP_GEN
);
533 if (mask
& IPU_CONF_DI0_EN
)
534 val
|= IPU_DI0_COUNTER_RELEASE
;
535 if (mask
& IPU_CONF_DI1_EN
)
536 val
|= IPU_DI1_COUNTER_RELEASE
;
538 ipu_cm_write(ipu
, val
, IPU_DISP_GEN
);
540 val
= ipu_cm_read(ipu
, IPU_CONF
);
542 ipu_cm_write(ipu
, val
, IPU_CONF
);
544 spin_unlock_irqrestore(&ipu
->lock
, lock_flags
);
548 EXPORT_SYMBOL_GPL(ipu_module_enable
);
550 int ipu_module_disable(struct ipu_soc
*ipu
, u32 mask
)
552 unsigned long lock_flags
;
555 spin_lock_irqsave(&ipu
->lock
, lock_flags
);
557 val
= ipu_cm_read(ipu
, IPU_CONF
);
559 ipu_cm_write(ipu
, val
, IPU_CONF
);
561 val
= ipu_cm_read(ipu
, IPU_DISP_GEN
);
563 if (mask
& IPU_CONF_DI0_EN
)
564 val
&= ~IPU_DI0_COUNTER_RELEASE
;
565 if (mask
& IPU_CONF_DI1_EN
)
566 val
&= ~IPU_DI1_COUNTER_RELEASE
;
568 ipu_cm_write(ipu
, val
, IPU_DISP_GEN
);
570 spin_unlock_irqrestore(&ipu
->lock
, lock_flags
);
574 EXPORT_SYMBOL_GPL(ipu_module_disable
);
576 void ipu_idmac_select_buffer(struct ipuv3_channel
*channel
, u32 buf_num
)
578 struct ipu_soc
*ipu
= channel
->ipu
;
579 unsigned int chno
= channel
->num
;
582 spin_lock_irqsave(&ipu
->lock
, flags
);
584 /* Mark buffer as ready. */
586 ipu_cm_write(ipu
, idma_mask(chno
), IPU_CHA_BUF0_RDY(chno
));
588 ipu_cm_write(ipu
, idma_mask(chno
), IPU_CHA_BUF1_RDY(chno
));
590 spin_unlock_irqrestore(&ipu
->lock
, flags
);
592 EXPORT_SYMBOL_GPL(ipu_idmac_select_buffer
);
594 int ipu_idmac_enable_channel(struct ipuv3_channel
*channel
)
596 struct ipu_soc
*ipu
= channel
->ipu
;
600 spin_lock_irqsave(&ipu
->lock
, flags
);
602 val
= ipu_idmac_read(ipu
, IDMAC_CHA_EN(channel
->num
));
603 val
|= idma_mask(channel
->num
);
604 ipu_idmac_write(ipu
, val
, IDMAC_CHA_EN(channel
->num
));
606 spin_unlock_irqrestore(&ipu
->lock
, flags
);
610 EXPORT_SYMBOL_GPL(ipu_idmac_enable_channel
);
612 int ipu_idmac_disable_channel(struct ipuv3_channel
*channel
)
614 struct ipu_soc
*ipu
= channel
->ipu
;
617 unsigned long timeout
;
619 timeout
= jiffies
+ msecs_to_jiffies(50);
620 while (ipu_idmac_read(ipu
, IDMAC_CHA_BUSY(channel
->num
)) &
621 idma_mask(channel
->num
)) {
622 if (time_after(jiffies
, timeout
)) {
623 dev_warn(ipu
->dev
, "disabling busy idmac channel %d\n",
630 spin_lock_irqsave(&ipu
->lock
, flags
);
632 /* Disable DMA channel(s) */
633 val
= ipu_idmac_read(ipu
, IDMAC_CHA_EN(channel
->num
));
634 val
&= ~idma_mask(channel
->num
);
635 ipu_idmac_write(ipu
, val
, IDMAC_CHA_EN(channel
->num
));
637 /* Set channel buffers NOT to be ready */
638 ipu_cm_write(ipu
, 0xf0000000, IPU_GPR
); /* write one to clear */
640 if (ipu_cm_read(ipu
, IPU_CHA_BUF0_RDY(channel
->num
)) &
641 idma_mask(channel
->num
)) {
642 ipu_cm_write(ipu
, idma_mask(channel
->num
),
643 IPU_CHA_BUF0_RDY(channel
->num
));
646 if (ipu_cm_read(ipu
, IPU_CHA_BUF1_RDY(channel
->num
)) &
647 idma_mask(channel
->num
)) {
648 ipu_cm_write(ipu
, idma_mask(channel
->num
),
649 IPU_CHA_BUF1_RDY(channel
->num
));
652 ipu_cm_write(ipu
, 0x0, IPU_GPR
); /* write one to set */
654 /* Reset the double buffer */
655 val
= ipu_cm_read(ipu
, IPU_CHA_DB_MODE_SEL(channel
->num
));
656 val
&= ~idma_mask(channel
->num
);
657 ipu_cm_write(ipu
, val
, IPU_CHA_DB_MODE_SEL(channel
->num
));
659 spin_unlock_irqrestore(&ipu
->lock
, flags
);
663 EXPORT_SYMBOL_GPL(ipu_idmac_disable_channel
);
665 static int ipu_memory_reset(struct ipu_soc
*ipu
)
667 unsigned long timeout
;
669 ipu_cm_write(ipu
, 0x807FFFFF, IPU_MEM_RST
);
671 timeout
= jiffies
+ msecs_to_jiffies(1000);
672 while (ipu_cm_read(ipu
, IPU_MEM_RST
) & 0x80000000) {
673 if (time_after(jiffies
, timeout
))
683 unsigned long cm_ofs
;
684 unsigned long cpmem_ofs
;
685 unsigned long srm_ofs
;
686 unsigned long tpm_ofs
;
687 unsigned long disp0_ofs
;
688 unsigned long disp1_ofs
;
689 unsigned long dc_tmpl_ofs
;
690 unsigned long vdi_ofs
;
691 enum ipuv3_type type
;
694 static struct ipu_devtype ipu_type_imx51
= {
696 .cm_ofs
= 0x1e000000,
697 .cpmem_ofs
= 0x1f000000,
698 .srm_ofs
= 0x1f040000,
699 .tpm_ofs
= 0x1f060000,
700 .disp0_ofs
= 0x1e040000,
701 .disp1_ofs
= 0x1e048000,
702 .dc_tmpl_ofs
= 0x1f080000,
703 .vdi_ofs
= 0x1e068000,
707 static struct ipu_devtype ipu_type_imx53
= {
709 .cm_ofs
= 0x06000000,
710 .cpmem_ofs
= 0x07000000,
711 .srm_ofs
= 0x07040000,
712 .tpm_ofs
= 0x07060000,
713 .disp0_ofs
= 0x06040000,
714 .disp1_ofs
= 0x06048000,
715 .dc_tmpl_ofs
= 0x07080000,
716 .vdi_ofs
= 0x06068000,
720 static struct ipu_devtype ipu_type_imx6q
= {
722 .cm_ofs
= 0x00200000,
723 .cpmem_ofs
= 0x00300000,
724 .srm_ofs
= 0x00340000,
725 .tpm_ofs
= 0x00360000,
726 .disp0_ofs
= 0x00240000,
727 .disp1_ofs
= 0x00248000,
728 .dc_tmpl_ofs
= 0x00380000,
729 .vdi_ofs
= 0x00268000,
733 static const struct of_device_id imx_ipu_dt_ids
[] = {
734 { .compatible
= "fsl,imx51-ipu", .data
= &ipu_type_imx51
, },
735 { .compatible
= "fsl,imx53-ipu", .data
= &ipu_type_imx53
, },
736 { .compatible
= "fsl,imx6q-ipu", .data
= &ipu_type_imx6q
, },
739 MODULE_DEVICE_TABLE(of
, imx_ipu_dt_ids
);
741 static int ipu_submodules_init(struct ipu_soc
*ipu
,
742 struct platform_device
*pdev
, unsigned long ipu_base
,
747 struct device
*dev
= &pdev
->dev
;
748 const struct ipu_devtype
*devtype
= ipu
->devtype
;
750 ret
= ipu_di_init(ipu
, dev
, 0, ipu_base
+ devtype
->disp0_ofs
,
751 IPU_CONF_DI0_EN
, ipu_clk
);
757 ret
= ipu_di_init(ipu
, dev
, 1, ipu_base
+ devtype
->disp1_ofs
,
758 IPU_CONF_DI1_EN
, ipu_clk
);
764 ret
= ipu_dc_init(ipu
, dev
, ipu_base
+ devtype
->cm_ofs
+
765 IPU_CM_DC_REG_OFS
, ipu_base
+ devtype
->dc_tmpl_ofs
);
767 unit
= "dc_template";
771 ret
= ipu_dmfc_init(ipu
, dev
, ipu_base
+
772 devtype
->cm_ofs
+ IPU_CM_DMFC_REG_OFS
, ipu_clk
);
778 ret
= ipu_dp_init(ipu
, dev
, ipu_base
+ devtype
->srm_ofs
);
795 dev_err(&pdev
->dev
, "init %s failed with %d\n", unit
, ret
);
799 static void ipu_irq_handle(struct ipu_soc
*ipu
, const int *regs
, int num_regs
)
801 unsigned long status
;
802 int i
, bit
, irq_base
;
804 for (i
= 0; i
< num_regs
; i
++) {
806 status
= ipu_cm_read(ipu
, IPU_INT_STAT(regs
[i
]));
807 status
&= ipu_cm_read(ipu
, IPU_INT_CTRL(regs
[i
]));
809 irq_base
= ipu
->irq_start
+ regs
[i
] * 32;
810 for_each_set_bit(bit
, &status
, 32)
811 generic_handle_irq(irq_base
+ bit
);
815 static void ipu_irq_handler(unsigned int irq
, struct irq_desc
*desc
)
817 struct ipu_soc
*ipu
= irq_desc_get_handler_data(desc
);
818 const int int_reg
[] = { 0, 1, 2, 3, 10, 11, 12, 13, 14};
819 struct irq_chip
*chip
= irq_get_chip(irq
);
821 chained_irq_enter(chip
, desc
);
823 ipu_irq_handle(ipu
, int_reg
, ARRAY_SIZE(int_reg
));
825 chained_irq_exit(chip
, desc
);
828 static void ipu_err_irq_handler(unsigned int irq
, struct irq_desc
*desc
)
830 struct ipu_soc
*ipu
= irq_desc_get_handler_data(desc
);
831 const int int_reg
[] = { 4, 5, 8, 9};
832 struct irq_chip
*chip
= irq_get_chip(irq
);
834 chained_irq_enter(chip
, desc
);
836 ipu_irq_handle(ipu
, int_reg
, ARRAY_SIZE(int_reg
));
838 chained_irq_exit(chip
, desc
);
841 static void ipu_ack_irq(struct irq_data
*d
)
843 struct ipu_soc
*ipu
= irq_data_get_irq_chip_data(d
);
844 unsigned int irq
= d
->irq
- ipu
->irq_start
;
846 ipu_cm_write(ipu
, 1 << (irq
% 32), IPU_INT_STAT(irq
/ 32));
849 static void ipu_unmask_irq(struct irq_data
*d
)
851 struct ipu_soc
*ipu
= irq_data_get_irq_chip_data(d
);
852 unsigned int irq
= d
->irq
- ipu
->irq_start
;
856 spin_lock_irqsave(&ipu
->lock
, flags
);
858 reg
= ipu_cm_read(ipu
, IPU_INT_CTRL(irq
/ 32));
859 reg
|= 1 << (irq
% 32);
860 ipu_cm_write(ipu
, reg
, IPU_INT_CTRL(irq
/ 32));
862 spin_unlock_irqrestore(&ipu
->lock
, flags
);
865 static void ipu_mask_irq(struct irq_data
*d
)
867 struct ipu_soc
*ipu
= irq_data_get_irq_chip_data(d
);
868 unsigned int irq
= d
->irq
- ipu
->irq_start
;
872 spin_lock_irqsave(&ipu
->lock
, flags
);
874 reg
= ipu_cm_read(ipu
, IPU_INT_CTRL(irq
/ 32));
875 reg
&= ~(1 << (irq
% 32));
876 ipu_cm_write(ipu
, reg
, IPU_INT_CTRL(irq
/ 32));
878 spin_unlock_irqrestore(&ipu
->lock
, flags
);
881 static struct irq_chip ipu_irq_chip
= {
883 .irq_ack
= ipu_ack_irq
,
884 .irq_mask
= ipu_mask_irq
,
885 .irq_unmask
= ipu_unmask_irq
,
888 int ipu_idmac_channel_irq(struct ipu_soc
*ipu
, struct ipuv3_channel
*channel
,
889 enum ipu_channel_irq irq_type
)
891 return ipu
->irq_start
+ irq_type
+ channel
->num
;
893 EXPORT_SYMBOL_GPL(ipu_idmac_channel_irq
);
895 static void ipu_submodules_exit(struct ipu_soc
*ipu
)
904 static int platform_remove_devices_fn(struct device
*dev
, void *unused
)
906 struct platform_device
*pdev
= to_platform_device(dev
);
908 platform_device_unregister(pdev
);
913 static void platform_device_unregister_children(struct platform_device
*pdev
)
915 device_for_each_child(&pdev
->dev
, NULL
, platform_remove_devices_fn
);
918 struct ipu_platform_reg
{
919 struct ipu_client_platformdata pdata
;
923 static const struct ipu_platform_reg client_reg
[] = {
928 .dp
= IPU_DP_FLOW_SYNC_BG
,
929 .dma
[0] = IPUV3_CHANNEL_MEM_BG_SYNC
,
932 .name
= "imx-ipuv3-crtc",
938 .dma
[0] = IPUV3_CHANNEL_MEM_DC_SYNC
,
941 .name
= "imx-ipuv3-crtc",
945 static int ipu_client_id
;
947 static int ipu_add_subdevice_pdata(struct device
*dev
,
948 const struct ipu_platform_reg
*reg
)
950 struct platform_device
*pdev
;
952 pdev
= platform_device_register_data(dev
, reg
->name
, ipu_client_id
++,
953 ®
->pdata
, sizeof(struct ipu_platform_reg
));
955 return pdev
? 0 : -EINVAL
;
958 static int ipu_add_client_devices(struct ipu_soc
*ipu
)
963 for (i
= 0; i
< ARRAY_SIZE(client_reg
); i
++) {
964 const struct ipu_platform_reg
*reg
= &client_reg
[i
];
965 ret
= ipu_add_subdevice_pdata(ipu
->dev
, reg
);
973 platform_device_unregister_children(to_platform_device(ipu
->dev
));
978 static int ipu_irq_init(struct ipu_soc
*ipu
)
982 ipu
->irq_start
= irq_alloc_descs(-1, 0, IPU_NUM_IRQS
, 0);
983 if (ipu
->irq_start
< 0)
984 return ipu
->irq_start
;
986 for (i
= ipu
->irq_start
; i
< ipu
->irq_start
+ IPU_NUM_IRQS
; i
++) {
987 irq_set_chip_and_handler(i
, &ipu_irq_chip
, handle_level_irq
);
988 set_irq_flags(i
, IRQF_VALID
);
989 irq_set_chip_data(i
, ipu
);
992 irq_set_chained_handler(ipu
->irq_sync
, ipu_irq_handler
);
993 irq_set_handler_data(ipu
->irq_sync
, ipu
);
994 irq_set_chained_handler(ipu
->irq_err
, ipu_err_irq_handler
);
995 irq_set_handler_data(ipu
->irq_err
, ipu
);
1000 static void ipu_irq_exit(struct ipu_soc
*ipu
)
1004 irq_set_chained_handler(ipu
->irq_err
, NULL
);
1005 irq_set_handler_data(ipu
->irq_err
, NULL
);
1006 irq_set_chained_handler(ipu
->irq_sync
, NULL
);
1007 irq_set_handler_data(ipu
->irq_sync
, NULL
);
1009 for (i
= ipu
->irq_start
; i
< ipu
->irq_start
+ IPU_NUM_IRQS
; i
++) {
1010 set_irq_flags(i
, 0);
1011 irq_set_chip(i
, NULL
);
1012 irq_set_chip_data(i
, NULL
);
1015 irq_free_descs(ipu
->irq_start
, IPU_NUM_IRQS
);
1018 static int ipu_probe(struct platform_device
*pdev
)
1020 const struct of_device_id
*of_id
=
1021 of_match_device(imx_ipu_dt_ids
, &pdev
->dev
);
1022 struct ipu_soc
*ipu
;
1023 struct resource
*res
;
1024 unsigned long ipu_base
;
1025 int i
, ret
, irq_sync
, irq_err
;
1026 const struct ipu_devtype
*devtype
;
1028 devtype
= of_id
->data
;
1030 irq_sync
= platform_get_irq(pdev
, 0);
1031 irq_err
= platform_get_irq(pdev
, 1);
1032 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
1034 dev_dbg(&pdev
->dev
, "irq_sync: %d irq_err: %d\n",
1037 if (!res
|| irq_sync
< 0 || irq_err
< 0)
1040 ipu_base
= res
->start
;
1042 ipu
= devm_kzalloc(&pdev
->dev
, sizeof(*ipu
), GFP_KERNEL
);
1046 for (i
= 0; i
< 64; i
++)
1047 ipu
->channel
[i
].ipu
= ipu
;
1048 ipu
->devtype
= devtype
;
1049 ipu
->ipu_type
= devtype
->type
;
1051 spin_lock_init(&ipu
->lock
);
1052 mutex_init(&ipu
->channel_lock
);
1054 dev_dbg(&pdev
->dev
, "cm_reg: 0x%08lx\n",
1055 ipu_base
+ devtype
->cm_ofs
);
1056 dev_dbg(&pdev
->dev
, "idmac: 0x%08lx\n",
1057 ipu_base
+ devtype
->cm_ofs
+ IPU_CM_IDMAC_REG_OFS
);
1058 dev_dbg(&pdev
->dev
, "cpmem: 0x%08lx\n",
1059 ipu_base
+ devtype
->cpmem_ofs
);
1060 dev_dbg(&pdev
->dev
, "disp0: 0x%08lx\n",
1061 ipu_base
+ devtype
->disp0_ofs
);
1062 dev_dbg(&pdev
->dev
, "disp1: 0x%08lx\n",
1063 ipu_base
+ devtype
->disp1_ofs
);
1064 dev_dbg(&pdev
->dev
, "srm: 0x%08lx\n",
1065 ipu_base
+ devtype
->srm_ofs
);
1066 dev_dbg(&pdev
->dev
, "tpm: 0x%08lx\n",
1067 ipu_base
+ devtype
->tpm_ofs
);
1068 dev_dbg(&pdev
->dev
, "dc: 0x%08lx\n",
1069 ipu_base
+ devtype
->cm_ofs
+ IPU_CM_DC_REG_OFS
);
1070 dev_dbg(&pdev
->dev
, "ic: 0x%08lx\n",
1071 ipu_base
+ devtype
->cm_ofs
+ IPU_CM_IC_REG_OFS
);
1072 dev_dbg(&pdev
->dev
, "dmfc: 0x%08lx\n",
1073 ipu_base
+ devtype
->cm_ofs
+ IPU_CM_DMFC_REG_OFS
);
1074 dev_dbg(&pdev
->dev
, "vdi: 0x%08lx\n",
1075 ipu_base
+ devtype
->vdi_ofs
);
1077 ipu
->cm_reg
= devm_ioremap(&pdev
->dev
,
1078 ipu_base
+ devtype
->cm_ofs
, PAGE_SIZE
);
1079 ipu
->idmac_reg
= devm_ioremap(&pdev
->dev
,
1080 ipu_base
+ devtype
->cm_ofs
+ IPU_CM_IDMAC_REG_OFS
,
1082 ipu
->cpmem_base
= devm_ioremap(&pdev
->dev
,
1083 ipu_base
+ devtype
->cpmem_ofs
, PAGE_SIZE
);
1085 if (!ipu
->cm_reg
|| !ipu
->idmac_reg
|| !ipu
->cpmem_base
) {
1087 goto failed_ioremap
;
1090 ipu
->clk
= devm_clk_get(&pdev
->dev
, "bus");
1091 if (IS_ERR(ipu
->clk
)) {
1092 ret
= PTR_ERR(ipu
->clk
);
1093 dev_err(&pdev
->dev
, "clk_get failed with %d", ret
);
1094 goto failed_clk_get
;
1097 platform_set_drvdata(pdev
, ipu
);
1099 clk_prepare_enable(ipu
->clk
);
1101 ipu
->dev
= &pdev
->dev
;
1102 ipu
->irq_sync
= irq_sync
;
1103 ipu
->irq_err
= irq_err
;
1105 ret
= ipu_irq_init(ipu
);
1107 goto out_failed_irq
;
1109 ret
= device_reset(&pdev
->dev
);
1111 dev_err(&pdev
->dev
, "failed to reset: %d\n", ret
);
1112 goto out_failed_reset
;
1114 ret
= ipu_memory_reset(ipu
);
1116 goto out_failed_reset
;
1118 /* Set MCU_T to divide MCU access window into 2 */
1119 ipu_cm_write(ipu
, 0x00400000L
| (IPU_MCU_T_DEFAULT
<< 18),
1122 ret
= ipu_submodules_init(ipu
, pdev
, ipu_base
, ipu
->clk
);
1124 goto failed_submodules_init
;
1126 ret
= ipu_add_client_devices(ipu
);
1128 dev_err(&pdev
->dev
, "adding client devices failed with %d\n",
1130 goto failed_add_clients
;
1133 dev_info(&pdev
->dev
, "%s probed\n", devtype
->name
);
1138 ipu_submodules_exit(ipu
);
1139 failed_submodules_init
:
1143 clk_disable_unprepare(ipu
->clk
);
1149 static int ipu_remove(struct platform_device
*pdev
)
1151 struct ipu_soc
*ipu
= platform_get_drvdata(pdev
);
1153 platform_device_unregister_children(pdev
);
1154 ipu_submodules_exit(ipu
);
1157 clk_disable_unprepare(ipu
->clk
);
1162 static struct platform_driver imx_ipu_driver
= {
1164 .name
= "imx-ipuv3",
1165 .of_match_table
= imx_ipu_dt_ids
,
1168 .remove
= ipu_remove
,
1171 module_platform_driver(imx_ipu_driver
);
1173 MODULE_DESCRIPTION("i.MX IPU v3 driver");
1174 MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>");
1175 MODULE_LICENSE("GPL");