• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2010 Sascha Hauer <s.hauer@pengutronix.de>
3  * Copyright (C) 2005-2009 Freescale Semiconductor, Inc.
4  *
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.
9  *
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
13  * for more details.
14  */
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>
25 #include <linux/io.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>
31 
32 #include "imx-ipu-v3.h"
33 #include "ipu-prv.h"
34 
ipu_cm_read(struct ipu_soc * ipu,unsigned offset)35 static inline u32 ipu_cm_read(struct ipu_soc *ipu, unsigned offset)
36 {
37 	return readl(ipu->cm_reg + offset);
38 }
39 
ipu_cm_write(struct ipu_soc * ipu,u32 value,unsigned offset)40 static inline void ipu_cm_write(struct ipu_soc *ipu, u32 value, unsigned offset)
41 {
42 	writel(value, ipu->cm_reg + offset);
43 }
44 
ipu_idmac_read(struct ipu_soc * ipu,unsigned offset)45 static inline u32 ipu_idmac_read(struct ipu_soc *ipu, unsigned offset)
46 {
47 	return readl(ipu->idmac_reg + offset);
48 }
49 
ipu_idmac_write(struct ipu_soc * ipu,u32 value,unsigned offset)50 static inline void ipu_idmac_write(struct ipu_soc *ipu, u32 value,
51 		unsigned offset)
52 {
53 	writel(value, ipu->idmac_reg + offset);
54 }
55 
ipu_srm_dp_sync_update(struct ipu_soc * ipu)56 void ipu_srm_dp_sync_update(struct ipu_soc *ipu)
57 {
58 	u32 val;
59 
60 	val = ipu_cm_read(ipu, IPU_SRM_PRI2);
61 	val |= 0x8;
62 	ipu_cm_write(ipu, val, IPU_SRM_PRI2);
63 }
64 EXPORT_SYMBOL_GPL(ipu_srm_dp_sync_update);
65 
ipu_get_cpmem(struct ipuv3_channel * channel)66 struct ipu_ch_param __iomem *ipu_get_cpmem(struct ipuv3_channel *channel)
67 {
68 	struct ipu_soc *ipu = channel->ipu;
69 
70 	return ipu->cpmem_base + channel->num;
71 }
72 EXPORT_SYMBOL_GPL(ipu_get_cpmem);
73 
ipu_cpmem_set_high_priority(struct ipuv3_channel * channel)74 void ipu_cpmem_set_high_priority(struct ipuv3_channel *channel)
75 {
76 	struct ipu_soc *ipu = channel->ipu;
77 	struct ipu_ch_param __iomem *p = ipu_get_cpmem(channel);
78 	u32 val;
79 
80 	if (ipu->ipu_type == IPUV3EX)
81 		ipu_ch_param_write_field(p, IPU_FIELD_ID, 1);
82 
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));
86 };
87 EXPORT_SYMBOL_GPL(ipu_cpmem_set_high_priority);
88 
ipu_ch_param_write_field(struct ipu_ch_param __iomem * base,u32 wbs,u32 v)89 void ipu_ch_param_write_field(struct ipu_ch_param __iomem *base, u32 wbs, u32 v)
90 {
91 	u32 bit = (wbs >> 8) % 160;
92 	u32 size = wbs & 0xff;
93 	u32 word = (wbs >> 8) / 160;
94 	u32 i = bit / 32;
95 	u32 ofs = bit % 32;
96 	u32 mask = (1 << size) - 1;
97 	u32 val;
98 
99 	pr_debug("%s %d %d %d\n", __func__, word, bit , size);
100 
101 	val = readl(&base->word[word].data[i]);
102 	val &= ~(mask << ofs);
103 	val |= v << ofs;
104 	writel(val, &base->word[word].data[i]);
105 
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]);
111 	}
112 }
113 EXPORT_SYMBOL_GPL(ipu_ch_param_write_field);
114 
ipu_ch_param_read_field(struct ipu_ch_param __iomem * base,u32 wbs)115 u32 ipu_ch_param_read_field(struct ipu_ch_param __iomem *base, u32 wbs)
116 {
117 	u32 bit = (wbs >> 8) % 160;
118 	u32 size = wbs & 0xff;
119 	u32 word = (wbs >> 8) / 160;
120 	u32 i = bit / 32;
121 	u32 ofs = bit % 32;
122 	u32 mask = (1 << size) - 1;
123 	u32 val = 0;
124 
125 	pr_debug("%s %d %d %d\n", __func__, word, bit , size);
126 
127 	val = (readl(&base->word[word].data[i]) >> ofs) & mask;
128 
129 	if ((bit + size - 1) / 32 > i) {
130 		u32 tmp;
131 		tmp = readl(&base->word[word].data[i + 1]);
132 		tmp &= mask >> (ofs ? (32 - ofs) : 0);
133 		val |= tmp << (ofs ? (32 - ofs) : 0);
134 	}
135 
136 	return val;
137 }
138 EXPORT_SYMBOL_GPL(ipu_ch_param_read_field);
139 
ipu_cpmem_set_format_rgb(struct ipu_ch_param __iomem * p,struct ipu_rgb * rgb)140 int ipu_cpmem_set_format_rgb(struct ipu_ch_param __iomem *p,
141 		struct ipu_rgb *rgb)
142 {
143 	int bpp = 0, npb = 0, ro, go, bo, to;
144 
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;
149 
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);
156 
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);
161 	} else {
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);
165 	}
166 
167 	switch (rgb->bits_per_pixel) {
168 	case 32:
169 		bpp = 0;
170 		npb = 15;
171 		break;
172 	case 24:
173 		bpp = 1;
174 		npb = 19;
175 		break;
176 	case 16:
177 		bpp = 3;
178 		npb = 31;
179 		break;
180 	case 8:
181 		bpp = 5;
182 		npb = 63;
183 		break;
184 	default:
185 		return -EINVAL;
186 	}
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 */
190 
191 	return 0;
192 }
193 EXPORT_SYMBOL_GPL(ipu_cpmem_set_format_rgb);
194 
ipu_cpmem_set_format_passthrough(struct ipu_ch_param __iomem * p,int width)195 int ipu_cpmem_set_format_passthrough(struct ipu_ch_param __iomem *p,
196 		int width)
197 {
198 	int bpp = 0, npb = 0;
199 
200 	switch (width) {
201 	case 32:
202 		bpp = 0;
203 		npb = 15;
204 		break;
205 	case 24:
206 		bpp = 1;
207 		npb = 19;
208 		break;
209 	case 16:
210 		bpp = 3;
211 		npb = 31;
212 		break;
213 	case 8:
214 		bpp = 5;
215 		npb = 63;
216 		break;
217 	default:
218 		return -EINVAL;
219 	}
220 
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 */
224 
225 	return 0;
226 }
227 EXPORT_SYMBOL_GPL(ipu_cpmem_set_format_passthrough);
228 
ipu_cpmem_set_yuv_interleaved(struct ipu_ch_param __iomem * p,u32 pixel_format)229 void ipu_cpmem_set_yuv_interleaved(struct ipu_ch_param __iomem *p,
230 				   u32 pixel_format)
231 {
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 */
237 		break;
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 */
242 		break;
243 	}
244 }
245 EXPORT_SYMBOL_GPL(ipu_cpmem_set_yuv_interleaved);
246 
ipu_cpmem_set_yuv_planar_full(struct ipu_ch_param __iomem * p,u32 pixel_format,int stride,int u_offset,int v_offset)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)
249 {
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);
255 		break;
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);
260 		break;
261 	}
262 }
263 EXPORT_SYMBOL_GPL(ipu_cpmem_set_yuv_planar_full);
264 
ipu_cpmem_set_yuv_planar(struct ipu_ch_param __iomem * p,u32 pixel_format,int stride,int height)265 void ipu_cpmem_set_yuv_planar(struct ipu_ch_param __iomem *p, u32 pixel_format,
266 		int stride, int height)
267 {
268 	int u_offset, v_offset;
269 	int uv_stride = 0;
270 
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,
278 				u_offset, v_offset);
279 		break;
280 	}
281 }
282 EXPORT_SYMBOL_GPL(ipu_cpmem_set_yuv_planar);
283 
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,
290 };
291 
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,
298 };
299 
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,
306 };
307 
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,
314 };
315 
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,
322 };
323 
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)
330 
ipu_cpmem_set_fmt(struct ipu_ch_param __iomem * cpmem,u32 pixelformat)331 int ipu_cpmem_set_fmt(struct ipu_ch_param __iomem *cpmem, u32 pixelformat)
332 {
333 	switch (pixelformat) {
334 	case V4L2_PIX_FMT_YUV420:
335 	case V4L2_PIX_FMT_YVU420:
336 		/* pix format */
337 		ipu_ch_param_write_field(cpmem, IPU_FIELD_PFS, 2);
338 		/* burst size */
339 		ipu_ch_param_write_field(cpmem, IPU_FIELD_NPB, 63);
340 		break;
341 	case V4L2_PIX_FMT_UYVY:
342 		/* bits/pixel */
343 		ipu_ch_param_write_field(cpmem, IPU_FIELD_BPP, 3);
344 		/* pix format */
345 		ipu_ch_param_write_field(cpmem, IPU_FIELD_PFS, 0xA);
346 		/* burst size */
347 		ipu_ch_param_write_field(cpmem, IPU_FIELD_NPB, 31);
348 		break;
349 	case V4L2_PIX_FMT_YUYV:
350 		/* bits/pixel */
351 		ipu_ch_param_write_field(cpmem, IPU_FIELD_BPP, 3);
352 		/* pix format */
353 		ipu_ch_param_write_field(cpmem, IPU_FIELD_PFS, 0x8);
354 		/* burst size */
355 		ipu_ch_param_write_field(cpmem, IPU_FIELD_NPB, 31);
356 		break;
357 	case V4L2_PIX_FMT_RGB32:
358 		ipu_cpmem_set_format_rgb(cpmem, &def_rgb_32);
359 		break;
360 	case V4L2_PIX_FMT_RGB565:
361 		ipu_cpmem_set_format_rgb(cpmem, &def_rgb_16);
362 		break;
363 	case V4L2_PIX_FMT_BGR32:
364 		ipu_cpmem_set_format_rgb(cpmem, &def_bgr_32);
365 		break;
366 	case V4L2_PIX_FMT_RGB24:
367 		ipu_cpmem_set_format_rgb(cpmem, &def_rgb_24);
368 		break;
369 	case V4L2_PIX_FMT_BGR24:
370 		ipu_cpmem_set_format_rgb(cpmem, &def_bgr_24);
371 		break;
372 	default:
373 		return -EINVAL;
374 	}
375 
376 	return 0;
377 }
378 EXPORT_SYMBOL_GPL(ipu_cpmem_set_fmt);
379 
ipu_cpmem_set_image(struct ipu_ch_param __iomem * cpmem,struct ipu_image * image)380 int ipu_cpmem_set_image(struct ipu_ch_param __iomem *cpmem,
381 		struct ipu_image *image)
382 {
383 	struct v4l2_pix_format *pix = &image->pix;
384 	int y_offset, u_offset, v_offset;
385 
386 	pr_debug("%s: resolution: %dx%d stride: %d\n",
387 			__func__, pix->width, pix->height,
388 			pix->bytesperline);
389 
390 	ipu_cpmem_set_resolution(cpmem, image->rect.width,
391 			image->rect.height);
392 	ipu_cpmem_set_stride(cpmem, pix->bytesperline);
393 
394 	ipu_cpmem_set_fmt(cpmem, pix->pixelformat);
395 
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;
404 
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);
408 		break;
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);
414 		break;
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);
420 		break;
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);
425 		break;
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);
431 		break;
432 	default:
433 		return -EINVAL;
434 	}
435 
436 	return 0;
437 }
438 EXPORT_SYMBOL_GPL(ipu_cpmem_set_image);
439 
ipu_pixelformat_to_colorspace(u32 pixelformat)440 enum ipu_color_space ipu_pixelformat_to_colorspace(u32 pixelformat)
441 {
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;
454 	default:
455 		return IPUV3_COLORSPACE_UNKNOWN;
456 	}
457 }
458 EXPORT_SYMBOL_GPL(ipu_pixelformat_to_colorspace);
459 
ipu_idmac_get(struct ipu_soc * ipu,unsigned num)460 struct ipuv3_channel *ipu_idmac_get(struct ipu_soc *ipu, unsigned num)
461 {
462 	struct ipuv3_channel *channel;
463 
464 	dev_dbg(ipu->dev, "%s %d\n", __func__, num);
465 
466 	if (num > 63)
467 		return ERR_PTR(-ENODEV);
468 
469 	mutex_lock(&ipu->channel_lock);
470 
471 	channel = &ipu->channel[num];
472 
473 	if (channel->busy) {
474 		channel = ERR_PTR(-EBUSY);
475 		goto out;
476 	}
477 
478 	channel->busy = 1;
479 	channel->num = num;
480 
481 out:
482 	mutex_unlock(&ipu->channel_lock);
483 
484 	return channel;
485 }
486 EXPORT_SYMBOL_GPL(ipu_idmac_get);
487 
ipu_idmac_put(struct ipuv3_channel * channel)488 void ipu_idmac_put(struct ipuv3_channel *channel)
489 {
490 	struct ipu_soc *ipu = channel->ipu;
491 
492 	dev_dbg(ipu->dev, "%s %d\n", __func__, channel->num);
493 
494 	mutex_lock(&ipu->channel_lock);
495 
496 	channel->busy = 0;
497 
498 	mutex_unlock(&ipu->channel_lock);
499 }
500 EXPORT_SYMBOL_GPL(ipu_idmac_put);
501 
502 #define idma_mask(ch)			(1 << (ch & 0x1f))
503 
ipu_idmac_set_double_buffer(struct ipuv3_channel * channel,bool doublebuffer)504 void ipu_idmac_set_double_buffer(struct ipuv3_channel *channel,
505 		bool doublebuffer)
506 {
507 	struct ipu_soc *ipu = channel->ipu;
508 	unsigned long flags;
509 	u32 reg;
510 
511 	spin_lock_irqsave(&ipu->lock, flags);
512 
513 	reg = ipu_cm_read(ipu, IPU_CHA_DB_MODE_SEL(channel->num));
514 	if (doublebuffer)
515 		reg |= idma_mask(channel->num);
516 	else
517 		reg &= ~idma_mask(channel->num);
518 	ipu_cm_write(ipu, reg, IPU_CHA_DB_MODE_SEL(channel->num));
519 
520 	spin_unlock_irqrestore(&ipu->lock, flags);
521 }
522 EXPORT_SYMBOL_GPL(ipu_idmac_set_double_buffer);
523 
ipu_module_enable(struct ipu_soc * ipu,u32 mask)524 int ipu_module_enable(struct ipu_soc *ipu, u32 mask)
525 {
526 	unsigned long lock_flags;
527 	u32 val;
528 
529 	spin_lock_irqsave(&ipu->lock, lock_flags);
530 
531 	val = ipu_cm_read(ipu, IPU_DISP_GEN);
532 
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;
537 
538 	ipu_cm_write(ipu, val, IPU_DISP_GEN);
539 
540 	val = ipu_cm_read(ipu, IPU_CONF);
541 	val |= mask;
542 	ipu_cm_write(ipu, val, IPU_CONF);
543 
544 	spin_unlock_irqrestore(&ipu->lock, lock_flags);
545 
546 	return 0;
547 }
548 EXPORT_SYMBOL_GPL(ipu_module_enable);
549 
ipu_module_disable(struct ipu_soc * ipu,u32 mask)550 int ipu_module_disable(struct ipu_soc *ipu, u32 mask)
551 {
552 	unsigned long lock_flags;
553 	u32 val;
554 
555 	spin_lock_irqsave(&ipu->lock, lock_flags);
556 
557 	val = ipu_cm_read(ipu, IPU_CONF);
558 	val &= ~mask;
559 	ipu_cm_write(ipu, val, IPU_CONF);
560 
561 	val = ipu_cm_read(ipu, IPU_DISP_GEN);
562 
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;
567 
568 	ipu_cm_write(ipu, val, IPU_DISP_GEN);
569 
570 	spin_unlock_irqrestore(&ipu->lock, lock_flags);
571 
572 	return 0;
573 }
574 EXPORT_SYMBOL_GPL(ipu_module_disable);
575 
ipu_idmac_select_buffer(struct ipuv3_channel * channel,u32 buf_num)576 void ipu_idmac_select_buffer(struct ipuv3_channel *channel, u32 buf_num)
577 {
578 	struct ipu_soc *ipu = channel->ipu;
579 	unsigned int chno = channel->num;
580 	unsigned long flags;
581 
582 	spin_lock_irqsave(&ipu->lock, flags);
583 
584 	/* Mark buffer as ready. */
585 	if (buf_num == 0)
586 		ipu_cm_write(ipu, idma_mask(chno), IPU_CHA_BUF0_RDY(chno));
587 	else
588 		ipu_cm_write(ipu, idma_mask(chno), IPU_CHA_BUF1_RDY(chno));
589 
590 	spin_unlock_irqrestore(&ipu->lock, flags);
591 }
592 EXPORT_SYMBOL_GPL(ipu_idmac_select_buffer);
593 
ipu_idmac_enable_channel(struct ipuv3_channel * channel)594 int ipu_idmac_enable_channel(struct ipuv3_channel *channel)
595 {
596 	struct ipu_soc *ipu = channel->ipu;
597 	u32 val;
598 	unsigned long flags;
599 
600 	spin_lock_irqsave(&ipu->lock, flags);
601 
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));
605 
606 	spin_unlock_irqrestore(&ipu->lock, flags);
607 
608 	return 0;
609 }
610 EXPORT_SYMBOL_GPL(ipu_idmac_enable_channel);
611 
ipu_idmac_disable_channel(struct ipuv3_channel * channel)612 int ipu_idmac_disable_channel(struct ipuv3_channel *channel)
613 {
614 	struct ipu_soc *ipu = channel->ipu;
615 	u32 val;
616 	unsigned long flags;
617 	unsigned long timeout;
618 
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",
624 					channel->num);
625 			break;
626 		}
627 		cpu_relax();
628 	}
629 
630 	spin_lock_irqsave(&ipu->lock, flags);
631 
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));
636 
637 	/* Set channel buffers NOT to be ready */
638 	ipu_cm_write(ipu, 0xf0000000, IPU_GPR); /* write one to clear */
639 
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));
644 	}
645 
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));
650 	}
651 
652 	ipu_cm_write(ipu, 0x0, IPU_GPR); /* write one to set */
653 
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));
658 
659 	spin_unlock_irqrestore(&ipu->lock, flags);
660 
661 	return 0;
662 }
663 EXPORT_SYMBOL_GPL(ipu_idmac_disable_channel);
664 
ipu_memory_reset(struct ipu_soc * ipu)665 static int ipu_memory_reset(struct ipu_soc *ipu)
666 {
667 	unsigned long timeout;
668 
669 	ipu_cm_write(ipu, 0x807FFFFF, IPU_MEM_RST);
670 
671 	timeout = jiffies + msecs_to_jiffies(1000);
672 	while (ipu_cm_read(ipu, IPU_MEM_RST) & 0x80000000) {
673 		if (time_after(jiffies, timeout))
674 			return -ETIME;
675 		cpu_relax();
676 	}
677 
678 	return 0;
679 }
680 
681 struct ipu_devtype {
682 	const char *name;
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;
692 };
693 
694 static struct ipu_devtype ipu_type_imx51 = {
695 	.name = "IPUv3EX",
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,
704 	.type = IPUV3EX,
705 };
706 
707 static struct ipu_devtype ipu_type_imx53 = {
708 	.name = "IPUv3M",
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,
717 	.type = IPUV3M,
718 };
719 
720 static struct ipu_devtype ipu_type_imx6q = {
721 	.name = "IPUv3H",
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,
730 	.type = IPUV3H,
731 };
732 
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, },
737 	{ /* sentinel */ }
738 };
739 MODULE_DEVICE_TABLE(of, imx_ipu_dt_ids);
740 
ipu_submodules_init(struct ipu_soc * ipu,struct platform_device * pdev,unsigned long ipu_base,struct clk * ipu_clk)741 static int ipu_submodules_init(struct ipu_soc *ipu,
742 		struct platform_device *pdev, unsigned long ipu_base,
743 		struct clk *ipu_clk)
744 {
745 	char *unit;
746 	int ret;
747 	struct device *dev = &pdev->dev;
748 	const struct ipu_devtype *devtype = ipu->devtype;
749 
750 	ret = ipu_di_init(ipu, dev, 0, ipu_base + devtype->disp0_ofs,
751 			IPU_CONF_DI0_EN, ipu_clk);
752 	if (ret) {
753 		unit = "di0";
754 		goto err_di_0;
755 	}
756 
757 	ret = ipu_di_init(ipu, dev, 1, ipu_base + devtype->disp1_ofs,
758 			IPU_CONF_DI1_EN, ipu_clk);
759 	if (ret) {
760 		unit = "di1";
761 		goto err_di_1;
762 	}
763 
764 	ret = ipu_dc_init(ipu, dev, ipu_base + devtype->cm_ofs +
765 			IPU_CM_DC_REG_OFS, ipu_base + devtype->dc_tmpl_ofs);
766 	if (ret) {
767 		unit = "dc_template";
768 		goto err_dc;
769 	}
770 
771 	ret = ipu_dmfc_init(ipu, dev, ipu_base +
772 			devtype->cm_ofs + IPU_CM_DMFC_REG_OFS, ipu_clk);
773 	if (ret) {
774 		unit = "dmfc";
775 		goto err_dmfc;
776 	}
777 
778 	ret = ipu_dp_init(ipu, dev, ipu_base + devtype->srm_ofs);
779 	if (ret) {
780 		unit = "dp";
781 		goto err_dp;
782 	}
783 
784 	return 0;
785 
786 err_dp:
787 	ipu_dmfc_exit(ipu);
788 err_dmfc:
789 	ipu_dc_exit(ipu);
790 err_dc:
791 	ipu_di_exit(ipu, 1);
792 err_di_1:
793 	ipu_di_exit(ipu, 0);
794 err_di_0:
795 	dev_err(&pdev->dev, "init %s failed with %d\n", unit, ret);
796 	return ret;
797 }
798 
ipu_irq_handle(struct ipu_soc * ipu,const int * regs,int num_regs)799 static void ipu_irq_handle(struct ipu_soc *ipu, const int *regs, int num_regs)
800 {
801 	unsigned long status;
802 	int i, bit, irq_base;
803 
804 	for (i = 0; i < num_regs; i++) {
805 
806 		status = ipu_cm_read(ipu, IPU_INT_STAT(regs[i]));
807 		status &= ipu_cm_read(ipu, IPU_INT_CTRL(regs[i]));
808 
809 		irq_base = ipu->irq_start + regs[i] * 32;
810 		for_each_set_bit(bit, &status, 32)
811 			generic_handle_irq(irq_base + bit);
812 	}
813 }
814 
ipu_irq_handler(unsigned int irq,struct irq_desc * desc)815 static void ipu_irq_handler(unsigned int irq, struct irq_desc *desc)
816 {
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);
820 
821 	chained_irq_enter(chip, desc);
822 
823 	ipu_irq_handle(ipu, int_reg, ARRAY_SIZE(int_reg));
824 
825 	chained_irq_exit(chip, desc);
826 }
827 
ipu_err_irq_handler(unsigned int irq,struct irq_desc * desc)828 static void ipu_err_irq_handler(unsigned int irq, struct irq_desc *desc)
829 {
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);
833 
834 	chained_irq_enter(chip, desc);
835 
836 	ipu_irq_handle(ipu, int_reg, ARRAY_SIZE(int_reg));
837 
838 	chained_irq_exit(chip, desc);
839 }
840 
ipu_ack_irq(struct irq_data * d)841 static void ipu_ack_irq(struct irq_data *d)
842 {
843 	struct ipu_soc *ipu = irq_data_get_irq_chip_data(d);
844 	unsigned int irq = d->irq - ipu->irq_start;
845 
846 	ipu_cm_write(ipu, 1 << (irq % 32), IPU_INT_STAT(irq / 32));
847 }
848 
ipu_unmask_irq(struct irq_data * d)849 static void ipu_unmask_irq(struct irq_data *d)
850 {
851 	struct ipu_soc *ipu = irq_data_get_irq_chip_data(d);
852 	unsigned int irq = d->irq - ipu->irq_start;
853 	unsigned long flags;
854 	u32 reg;
855 
856 	spin_lock_irqsave(&ipu->lock, flags);
857 
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));
861 
862 	spin_unlock_irqrestore(&ipu->lock, flags);
863 }
864 
ipu_mask_irq(struct irq_data * d)865 static void ipu_mask_irq(struct irq_data *d)
866 {
867 	struct ipu_soc *ipu = irq_data_get_irq_chip_data(d);
868 	unsigned int irq = d->irq - ipu->irq_start;
869 	unsigned long flags;
870 	u32 reg;
871 
872 	spin_lock_irqsave(&ipu->lock, flags);
873 
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));
877 
878 	spin_unlock_irqrestore(&ipu->lock, flags);
879 }
880 
881 static struct irq_chip ipu_irq_chip = {
882 	.name = "IPU",
883 	.irq_ack = ipu_ack_irq,
884 	.irq_mask = ipu_mask_irq,
885 	.irq_unmask = ipu_unmask_irq,
886 };
887 
ipu_idmac_channel_irq(struct ipu_soc * ipu,struct ipuv3_channel * channel,enum ipu_channel_irq irq_type)888 int ipu_idmac_channel_irq(struct ipu_soc *ipu, struct ipuv3_channel *channel,
889 		enum ipu_channel_irq irq_type)
890 {
891 	return ipu->irq_start + irq_type + channel->num;
892 }
893 EXPORT_SYMBOL_GPL(ipu_idmac_channel_irq);
894 
ipu_submodules_exit(struct ipu_soc * ipu)895 static void ipu_submodules_exit(struct ipu_soc *ipu)
896 {
897 	ipu_dp_exit(ipu);
898 	ipu_dmfc_exit(ipu);
899 	ipu_dc_exit(ipu);
900 	ipu_di_exit(ipu, 1);
901 	ipu_di_exit(ipu, 0);
902 }
903 
platform_remove_devices_fn(struct device * dev,void * unused)904 static int platform_remove_devices_fn(struct device *dev, void *unused)
905 {
906 	struct platform_device *pdev = to_platform_device(dev);
907 
908 	platform_device_unregister(pdev);
909 
910 	return 0;
911 }
912 
platform_device_unregister_children(struct platform_device * pdev)913 static void platform_device_unregister_children(struct platform_device *pdev)
914 {
915 	device_for_each_child(&pdev->dev, NULL, platform_remove_devices_fn);
916 }
917 
918 struct ipu_platform_reg {
919 	struct ipu_client_platformdata pdata;
920 	const char *name;
921 };
922 
923 static const struct ipu_platform_reg client_reg[] = {
924 	{
925 		.pdata = {
926 			.di = 0,
927 			.dc = 5,
928 			.dp = IPU_DP_FLOW_SYNC_BG,
929 			.dma[0] = IPUV3_CHANNEL_MEM_BG_SYNC,
930 			.dma[1] = -EINVAL,
931 		},
932 		.name = "imx-ipuv3-crtc",
933 	}, {
934 		.pdata = {
935 			.di = 1,
936 			.dc = 1,
937 			.dp = -EINVAL,
938 			.dma[0] = IPUV3_CHANNEL_MEM_DC_SYNC,
939 			.dma[1] = -EINVAL,
940 		},
941 		.name = "imx-ipuv3-crtc",
942 	},
943 };
944 
945 static int ipu_client_id;
946 
ipu_add_subdevice_pdata(struct device * dev,const struct ipu_platform_reg * reg)947 static int ipu_add_subdevice_pdata(struct device *dev,
948 		const struct ipu_platform_reg *reg)
949 {
950 	struct platform_device *pdev;
951 
952 	pdev = platform_device_register_data(dev, reg->name, ipu_client_id++,
953 			&reg->pdata, sizeof(struct ipu_platform_reg));
954 
955 	return pdev ? 0 : -EINVAL;
956 }
957 
ipu_add_client_devices(struct ipu_soc * ipu)958 static int ipu_add_client_devices(struct ipu_soc *ipu)
959 {
960 	int ret;
961 	int i;
962 
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);
966 		if (ret)
967 			goto err_register;
968 	}
969 
970 	return 0;
971 
972 err_register:
973 	platform_device_unregister_children(to_platform_device(ipu->dev));
974 
975 	return ret;
976 }
977 
ipu_irq_init(struct ipu_soc * ipu)978 static int ipu_irq_init(struct ipu_soc *ipu)
979 {
980 	int i;
981 
982 	ipu->irq_start = irq_alloc_descs(-1, 0, IPU_NUM_IRQS, 0);
983 	if (ipu->irq_start < 0)
984 		return ipu->irq_start;
985 
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);
990 	}
991 
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);
996 
997 	return 0;
998 }
999 
ipu_irq_exit(struct ipu_soc * ipu)1000 static void ipu_irq_exit(struct ipu_soc *ipu)
1001 {
1002 	int i;
1003 
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);
1008 
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);
1013 	}
1014 
1015 	irq_free_descs(ipu->irq_start, IPU_NUM_IRQS);
1016 }
1017 
ipu_probe(struct platform_device * pdev)1018 static int ipu_probe(struct platform_device *pdev)
1019 {
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;
1027 
1028 	devtype = of_id->data;
1029 
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);
1033 
1034 	dev_dbg(&pdev->dev, "irq_sync: %d irq_err: %d\n",
1035 			irq_sync, irq_err);
1036 
1037 	if (!res || irq_sync < 0 || irq_err < 0)
1038 		return -ENODEV;
1039 
1040 	ipu_base = res->start;
1041 
1042 	ipu = devm_kzalloc(&pdev->dev, sizeof(*ipu), GFP_KERNEL);
1043 	if (!ipu)
1044 		return -ENODEV;
1045 
1046 	for (i = 0; i < 64; i++)
1047 		ipu->channel[i].ipu = ipu;
1048 	ipu->devtype = devtype;
1049 	ipu->ipu_type = devtype->type;
1050 
1051 	spin_lock_init(&ipu->lock);
1052 	mutex_init(&ipu->channel_lock);
1053 
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);
1076 
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,
1081 			PAGE_SIZE);
1082 	ipu->cpmem_base = devm_ioremap(&pdev->dev,
1083 			ipu_base + devtype->cpmem_ofs, PAGE_SIZE);
1084 
1085 	if (!ipu->cm_reg || !ipu->idmac_reg || !ipu->cpmem_base) {
1086 		ret = -ENOMEM;
1087 		goto failed_ioremap;
1088 	}
1089 
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;
1095 	}
1096 
1097 	platform_set_drvdata(pdev, ipu);
1098 
1099 	clk_prepare_enable(ipu->clk);
1100 
1101 	ipu->dev = &pdev->dev;
1102 	ipu->irq_sync = irq_sync;
1103 	ipu->irq_err = irq_err;
1104 
1105 	ret = ipu_irq_init(ipu);
1106 	if (ret)
1107 		goto out_failed_irq;
1108 
1109 	ret = device_reset(&pdev->dev);
1110 	if (ret) {
1111 		dev_err(&pdev->dev, "failed to reset: %d\n", ret);
1112 		goto out_failed_reset;
1113 	}
1114 	ret = ipu_memory_reset(ipu);
1115 	if (ret)
1116 		goto out_failed_reset;
1117 
1118 	/* Set MCU_T to divide MCU access window into 2 */
1119 	ipu_cm_write(ipu, 0x00400000L | (IPU_MCU_T_DEFAULT << 18),
1120 			IPU_DISP_GEN);
1121 
1122 	ret = ipu_submodules_init(ipu, pdev, ipu_base, ipu->clk);
1123 	if (ret)
1124 		goto failed_submodules_init;
1125 
1126 	ret = ipu_add_client_devices(ipu);
1127 	if (ret) {
1128 		dev_err(&pdev->dev, "adding client devices failed with %d\n",
1129 				ret);
1130 		goto failed_add_clients;
1131 	}
1132 
1133 	dev_info(&pdev->dev, "%s probed\n", devtype->name);
1134 
1135 	return 0;
1136 
1137 failed_add_clients:
1138 	ipu_submodules_exit(ipu);
1139 failed_submodules_init:
1140 out_failed_reset:
1141 	ipu_irq_exit(ipu);
1142 out_failed_irq:
1143 	clk_disable_unprepare(ipu->clk);
1144 failed_clk_get:
1145 failed_ioremap:
1146 	return ret;
1147 }
1148 
ipu_remove(struct platform_device * pdev)1149 static int ipu_remove(struct platform_device *pdev)
1150 {
1151 	struct ipu_soc *ipu = platform_get_drvdata(pdev);
1152 
1153 	platform_device_unregister_children(pdev);
1154 	ipu_submodules_exit(ipu);
1155 	ipu_irq_exit(ipu);
1156 
1157 	clk_disable_unprepare(ipu->clk);
1158 
1159 	return 0;
1160 }
1161 
1162 static struct platform_driver imx_ipu_driver = {
1163 	.driver = {
1164 		.name = "imx-ipuv3",
1165 		.of_match_table = imx_ipu_dt_ids,
1166 	},
1167 	.probe = ipu_probe,
1168 	.remove = ipu_remove,
1169 };
1170 
1171 module_platform_driver(imx_ipu_driver);
1172 
1173 MODULE_DESCRIPTION("i.MX IPU v3 driver");
1174 MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>");
1175 MODULE_LICENSE("GPL");
1176