xref: /openbmc/linux/drivers/gpu/drm/exynos/exynos_mixer.c (revision bbde9fc1824aab58bc78c084163007dd6c03fe5b)
1 /*
2  * Copyright (C) 2011 Samsung Electronics Co.Ltd
3  * Authors:
4  * Seung-Woo Kim <sw0312.kim@samsung.com>
5  *	Inki Dae <inki.dae@samsung.com>
6  *	Joonyoung Shim <jy0922.shim@samsung.com>
7  *
8  * Based on drivers/media/video/s5p-tv/mixer_reg.c
9  *
10  * This program is free software; you can redistribute  it and/or modify it
11  * under  the terms of  the GNU General  Public License as published by the
12  * Free Software Foundation;  either version 2 of the  License, or (at your
13  * option) any later version.
14  *
15  */
16 
17 #include <drm/drmP.h>
18 
19 #include "regs-mixer.h"
20 #include "regs-vp.h"
21 
22 #include <linux/kernel.h>
23 #include <linux/spinlock.h>
24 #include <linux/wait.h>
25 #include <linux/i2c.h>
26 #include <linux/platform_device.h>
27 #include <linux/interrupt.h>
28 #include <linux/irq.h>
29 #include <linux/delay.h>
30 #include <linux/pm_runtime.h>
31 #include <linux/clk.h>
32 #include <linux/regulator/consumer.h>
33 #include <linux/of.h>
34 #include <linux/component.h>
35 
36 #include <drm/exynos_drm.h>
37 
38 #include "exynos_drm_drv.h"
39 #include "exynos_drm_crtc.h"
40 #include "exynos_drm_plane.h"
41 #include "exynos_drm_iommu.h"
42 #include "exynos_mixer.h"
43 
44 #define MIXER_WIN_NR		3
45 #define MIXER_DEFAULT_WIN	0
46 
47 /* The pixelformats that are natively supported by the mixer. */
48 #define MXR_FORMAT_RGB565	4
49 #define MXR_FORMAT_ARGB1555	5
50 #define MXR_FORMAT_ARGB4444	6
51 #define MXR_FORMAT_ARGB8888	7
52 
53 struct mixer_resources {
54 	int			irq;
55 	void __iomem		*mixer_regs;
56 	void __iomem		*vp_regs;
57 	spinlock_t		reg_slock;
58 	struct clk		*mixer;
59 	struct clk		*vp;
60 	struct clk		*hdmi;
61 	struct clk		*sclk_mixer;
62 	struct clk		*sclk_hdmi;
63 	struct clk		*mout_mixer;
64 };
65 
66 enum mixer_version_id {
67 	MXR_VER_0_0_0_16,
68 	MXR_VER_16_0_33_0,
69 	MXR_VER_128_0_0_184,
70 };
71 
72 struct mixer_context {
73 	struct platform_device *pdev;
74 	struct device		*dev;
75 	struct drm_device	*drm_dev;
76 	struct exynos_drm_crtc	*crtc;
77 	struct exynos_drm_plane	planes[MIXER_WIN_NR];
78 	int			pipe;
79 	bool			interlace;
80 	bool			powered;
81 	bool			vp_enabled;
82 	bool			has_sclk;
83 	u32			int_en;
84 
85 	struct mutex		mixer_mutex;
86 	struct mixer_resources	mixer_res;
87 	enum mixer_version_id	mxr_ver;
88 	wait_queue_head_t	wait_vsync_queue;
89 	atomic_t		wait_vsync_event;
90 };
91 
92 struct mixer_drv_data {
93 	enum mixer_version_id	version;
94 	bool					is_vp_enabled;
95 	bool					has_sclk;
96 };
97 
98 static const u8 filter_y_horiz_tap8[] = {
99 	0,	-1,	-1,	-1,	-1,	-1,	-1,	-1,
100 	-1,	-1,	-1,	-1,	-1,	0,	0,	0,
101 	0,	2,	4,	5,	6,	6,	6,	6,
102 	6,	5,	5,	4,	3,	2,	1,	1,
103 	0,	-6,	-12,	-16,	-18,	-20,	-21,	-20,
104 	-20,	-18,	-16,	-13,	-10,	-8,	-5,	-2,
105 	127,	126,	125,	121,	114,	107,	99,	89,
106 	79,	68,	57,	46,	35,	25,	16,	8,
107 };
108 
109 static const u8 filter_y_vert_tap4[] = {
110 	0,	-3,	-6,	-8,	-8,	-8,	-8,	-7,
111 	-6,	-5,	-4,	-3,	-2,	-1,	-1,	0,
112 	127,	126,	124,	118,	111,	102,	92,	81,
113 	70,	59,	48,	37,	27,	19,	11,	5,
114 	0,	5,	11,	19,	27,	37,	48,	59,
115 	70,	81,	92,	102,	111,	118,	124,	126,
116 	0,	0,	-1,	-1,	-2,	-3,	-4,	-5,
117 	-6,	-7,	-8,	-8,	-8,	-8,	-6,	-3,
118 };
119 
120 static const u8 filter_cr_horiz_tap4[] = {
121 	0,	-3,	-6,	-8,	-8,	-8,	-8,	-7,
122 	-6,	-5,	-4,	-3,	-2,	-1,	-1,	0,
123 	127,	126,	124,	118,	111,	102,	92,	81,
124 	70,	59,	48,	37,	27,	19,	11,	5,
125 };
126 
127 static inline u32 vp_reg_read(struct mixer_resources *res, u32 reg_id)
128 {
129 	return readl(res->vp_regs + reg_id);
130 }
131 
132 static inline void vp_reg_write(struct mixer_resources *res, u32 reg_id,
133 				 u32 val)
134 {
135 	writel(val, res->vp_regs + reg_id);
136 }
137 
138 static inline void vp_reg_writemask(struct mixer_resources *res, u32 reg_id,
139 				 u32 val, u32 mask)
140 {
141 	u32 old = vp_reg_read(res, reg_id);
142 
143 	val = (val & mask) | (old & ~mask);
144 	writel(val, res->vp_regs + reg_id);
145 }
146 
147 static inline u32 mixer_reg_read(struct mixer_resources *res, u32 reg_id)
148 {
149 	return readl(res->mixer_regs + reg_id);
150 }
151 
152 static inline void mixer_reg_write(struct mixer_resources *res, u32 reg_id,
153 				 u32 val)
154 {
155 	writel(val, res->mixer_regs + reg_id);
156 }
157 
158 static inline void mixer_reg_writemask(struct mixer_resources *res,
159 				 u32 reg_id, u32 val, u32 mask)
160 {
161 	u32 old = mixer_reg_read(res, reg_id);
162 
163 	val = (val & mask) | (old & ~mask);
164 	writel(val, res->mixer_regs + reg_id);
165 }
166 
167 static void mixer_regs_dump(struct mixer_context *ctx)
168 {
169 #define DUMPREG(reg_id) \
170 do { \
171 	DRM_DEBUG_KMS(#reg_id " = %08x\n", \
172 		(u32)readl(ctx->mixer_res.mixer_regs + reg_id)); \
173 } while (0)
174 
175 	DUMPREG(MXR_STATUS);
176 	DUMPREG(MXR_CFG);
177 	DUMPREG(MXR_INT_EN);
178 	DUMPREG(MXR_INT_STATUS);
179 
180 	DUMPREG(MXR_LAYER_CFG);
181 	DUMPREG(MXR_VIDEO_CFG);
182 
183 	DUMPREG(MXR_GRAPHIC0_CFG);
184 	DUMPREG(MXR_GRAPHIC0_BASE);
185 	DUMPREG(MXR_GRAPHIC0_SPAN);
186 	DUMPREG(MXR_GRAPHIC0_WH);
187 	DUMPREG(MXR_GRAPHIC0_SXY);
188 	DUMPREG(MXR_GRAPHIC0_DXY);
189 
190 	DUMPREG(MXR_GRAPHIC1_CFG);
191 	DUMPREG(MXR_GRAPHIC1_BASE);
192 	DUMPREG(MXR_GRAPHIC1_SPAN);
193 	DUMPREG(MXR_GRAPHIC1_WH);
194 	DUMPREG(MXR_GRAPHIC1_SXY);
195 	DUMPREG(MXR_GRAPHIC1_DXY);
196 #undef DUMPREG
197 }
198 
199 static void vp_regs_dump(struct mixer_context *ctx)
200 {
201 #define DUMPREG(reg_id) \
202 do { \
203 	DRM_DEBUG_KMS(#reg_id " = %08x\n", \
204 		(u32) readl(ctx->mixer_res.vp_regs + reg_id)); \
205 } while (0)
206 
207 	DUMPREG(VP_ENABLE);
208 	DUMPREG(VP_SRESET);
209 	DUMPREG(VP_SHADOW_UPDATE);
210 	DUMPREG(VP_FIELD_ID);
211 	DUMPREG(VP_MODE);
212 	DUMPREG(VP_IMG_SIZE_Y);
213 	DUMPREG(VP_IMG_SIZE_C);
214 	DUMPREG(VP_PER_RATE_CTRL);
215 	DUMPREG(VP_TOP_Y_PTR);
216 	DUMPREG(VP_BOT_Y_PTR);
217 	DUMPREG(VP_TOP_C_PTR);
218 	DUMPREG(VP_BOT_C_PTR);
219 	DUMPREG(VP_ENDIAN_MODE);
220 	DUMPREG(VP_SRC_H_POSITION);
221 	DUMPREG(VP_SRC_V_POSITION);
222 	DUMPREG(VP_SRC_WIDTH);
223 	DUMPREG(VP_SRC_HEIGHT);
224 	DUMPREG(VP_DST_H_POSITION);
225 	DUMPREG(VP_DST_V_POSITION);
226 	DUMPREG(VP_DST_WIDTH);
227 	DUMPREG(VP_DST_HEIGHT);
228 	DUMPREG(VP_H_RATIO);
229 	DUMPREG(VP_V_RATIO);
230 
231 #undef DUMPREG
232 }
233 
234 static inline void vp_filter_set(struct mixer_resources *res,
235 		int reg_id, const u8 *data, unsigned int size)
236 {
237 	/* assure 4-byte align */
238 	BUG_ON(size & 3);
239 	for (; size; size -= 4, reg_id += 4, data += 4) {
240 		u32 val = (data[0] << 24) |  (data[1] << 16) |
241 			(data[2] << 8) | data[3];
242 		vp_reg_write(res, reg_id, val);
243 	}
244 }
245 
246 static void vp_default_filter(struct mixer_resources *res)
247 {
248 	vp_filter_set(res, VP_POLY8_Y0_LL,
249 		filter_y_horiz_tap8, sizeof(filter_y_horiz_tap8));
250 	vp_filter_set(res, VP_POLY4_Y0_LL,
251 		filter_y_vert_tap4, sizeof(filter_y_vert_tap4));
252 	vp_filter_set(res, VP_POLY4_C0_LL,
253 		filter_cr_horiz_tap4, sizeof(filter_cr_horiz_tap4));
254 }
255 
256 static void mixer_vsync_set_update(struct mixer_context *ctx, bool enable)
257 {
258 	struct mixer_resources *res = &ctx->mixer_res;
259 
260 	/* block update on vsync */
261 	mixer_reg_writemask(res, MXR_STATUS, enable ?
262 			MXR_STATUS_SYNC_ENABLE : 0, MXR_STATUS_SYNC_ENABLE);
263 
264 	if (ctx->vp_enabled)
265 		vp_reg_write(res, VP_SHADOW_UPDATE, enable ?
266 			VP_SHADOW_UPDATE_ENABLE : 0);
267 }
268 
269 static void mixer_cfg_scan(struct mixer_context *ctx, unsigned int height)
270 {
271 	struct mixer_resources *res = &ctx->mixer_res;
272 	u32 val;
273 
274 	/* choosing between interlace and progressive mode */
275 	val = (ctx->interlace ? MXR_CFG_SCAN_INTERLACE :
276 				MXR_CFG_SCAN_PROGRESSIVE);
277 
278 	if (ctx->mxr_ver != MXR_VER_128_0_0_184) {
279 		/* choosing between proper HD and SD mode */
280 		if (height <= 480)
281 			val |= MXR_CFG_SCAN_NTSC | MXR_CFG_SCAN_SD;
282 		else if (height <= 576)
283 			val |= MXR_CFG_SCAN_PAL | MXR_CFG_SCAN_SD;
284 		else if (height <= 720)
285 			val |= MXR_CFG_SCAN_HD_720 | MXR_CFG_SCAN_HD;
286 		else if (height <= 1080)
287 			val |= MXR_CFG_SCAN_HD_1080 | MXR_CFG_SCAN_HD;
288 		else
289 			val |= MXR_CFG_SCAN_HD_720 | MXR_CFG_SCAN_HD;
290 	}
291 
292 	mixer_reg_writemask(res, MXR_CFG, val, MXR_CFG_SCAN_MASK);
293 }
294 
295 static void mixer_cfg_rgb_fmt(struct mixer_context *ctx, unsigned int height)
296 {
297 	struct mixer_resources *res = &ctx->mixer_res;
298 	u32 val;
299 
300 	if (height == 480) {
301 		val = MXR_CFG_RGB601_0_255;
302 	} else if (height == 576) {
303 		val = MXR_CFG_RGB601_0_255;
304 	} else if (height == 720) {
305 		val = MXR_CFG_RGB709_16_235;
306 		mixer_reg_write(res, MXR_CM_COEFF_Y,
307 				(1 << 30) | (94 << 20) | (314 << 10) |
308 				(32 << 0));
309 		mixer_reg_write(res, MXR_CM_COEFF_CB,
310 				(972 << 20) | (851 << 10) | (225 << 0));
311 		mixer_reg_write(res, MXR_CM_COEFF_CR,
312 				(225 << 20) | (820 << 10) | (1004 << 0));
313 	} else if (height == 1080) {
314 		val = MXR_CFG_RGB709_16_235;
315 		mixer_reg_write(res, MXR_CM_COEFF_Y,
316 				(1 << 30) | (94 << 20) | (314 << 10) |
317 				(32 << 0));
318 		mixer_reg_write(res, MXR_CM_COEFF_CB,
319 				(972 << 20) | (851 << 10) | (225 << 0));
320 		mixer_reg_write(res, MXR_CM_COEFF_CR,
321 				(225 << 20) | (820 << 10) | (1004 << 0));
322 	} else {
323 		val = MXR_CFG_RGB709_16_235;
324 		mixer_reg_write(res, MXR_CM_COEFF_Y,
325 				(1 << 30) | (94 << 20) | (314 << 10) |
326 				(32 << 0));
327 		mixer_reg_write(res, MXR_CM_COEFF_CB,
328 				(972 << 20) | (851 << 10) | (225 << 0));
329 		mixer_reg_write(res, MXR_CM_COEFF_CR,
330 				(225 << 20) | (820 << 10) | (1004 << 0));
331 	}
332 
333 	mixer_reg_writemask(res, MXR_CFG, val, MXR_CFG_RGB_FMT_MASK);
334 }
335 
336 static void mixer_cfg_layer(struct mixer_context *ctx, unsigned int win,
337 				bool enable)
338 {
339 	struct mixer_resources *res = &ctx->mixer_res;
340 	u32 val = enable ? ~0 : 0;
341 
342 	switch (win) {
343 	case 0:
344 		mixer_reg_writemask(res, MXR_CFG, val, MXR_CFG_GRP0_ENABLE);
345 		break;
346 	case 1:
347 		mixer_reg_writemask(res, MXR_CFG, val, MXR_CFG_GRP1_ENABLE);
348 		break;
349 	case 2:
350 		if (ctx->vp_enabled) {
351 			vp_reg_writemask(res, VP_ENABLE, val, VP_ENABLE_ON);
352 			mixer_reg_writemask(res, MXR_CFG, val,
353 				MXR_CFG_VP_ENABLE);
354 
355 			/* control blending of graphic layer 0 */
356 			mixer_reg_writemask(res, MXR_GRAPHIC_CFG(0), val,
357 					MXR_GRP_CFG_BLEND_PRE_MUL |
358 					MXR_GRP_CFG_PIXEL_BLEND_EN);
359 		}
360 		break;
361 	}
362 }
363 
364 static void mixer_run(struct mixer_context *ctx)
365 {
366 	struct mixer_resources *res = &ctx->mixer_res;
367 
368 	mixer_reg_writemask(res, MXR_STATUS, ~0, MXR_STATUS_REG_RUN);
369 }
370 
371 static void mixer_stop(struct mixer_context *ctx)
372 {
373 	struct mixer_resources *res = &ctx->mixer_res;
374 	int timeout = 20;
375 
376 	mixer_reg_writemask(res, MXR_STATUS, 0, MXR_STATUS_REG_RUN);
377 
378 	while (!(mixer_reg_read(res, MXR_STATUS) & MXR_STATUS_REG_IDLE) &&
379 			--timeout)
380 		usleep_range(10000, 12000);
381 }
382 
383 static void vp_video_buffer(struct mixer_context *ctx, unsigned int win)
384 {
385 	struct mixer_resources *res = &ctx->mixer_res;
386 	unsigned long flags;
387 	struct exynos_drm_plane *plane;
388 	dma_addr_t luma_addr[2], chroma_addr[2];
389 	bool tiled_mode = false;
390 	bool crcb_mode = false;
391 	u32 val;
392 
393 	plane = &ctx->planes[win];
394 
395 	switch (plane->pixel_format) {
396 	case DRM_FORMAT_NV12:
397 		crcb_mode = false;
398 		break;
399 	case DRM_FORMAT_NV21:
400 		crcb_mode = true;
401 		break;
402 	default:
403 		DRM_ERROR("pixel format for vp is wrong [%d].\n",
404 				plane->pixel_format);
405 		return;
406 	}
407 
408 	luma_addr[0] = plane->dma_addr[0];
409 	chroma_addr[0] = plane->dma_addr[1];
410 
411 	if (plane->scan_flag & DRM_MODE_FLAG_INTERLACE) {
412 		ctx->interlace = true;
413 		if (tiled_mode) {
414 			luma_addr[1] = luma_addr[0] + 0x40;
415 			chroma_addr[1] = chroma_addr[0] + 0x40;
416 		} else {
417 			luma_addr[1] = luma_addr[0] + plane->pitch;
418 			chroma_addr[1] = chroma_addr[0] + plane->pitch;
419 		}
420 	} else {
421 		ctx->interlace = false;
422 		luma_addr[1] = 0;
423 		chroma_addr[1] = 0;
424 	}
425 
426 	spin_lock_irqsave(&res->reg_slock, flags);
427 	mixer_vsync_set_update(ctx, false);
428 
429 	/* interlace or progressive scan mode */
430 	val = (ctx->interlace ? ~0 : 0);
431 	vp_reg_writemask(res, VP_MODE, val, VP_MODE_LINE_SKIP);
432 
433 	/* setup format */
434 	val = (crcb_mode ? VP_MODE_NV21 : VP_MODE_NV12);
435 	val |= (tiled_mode ? VP_MODE_MEM_TILED : VP_MODE_MEM_LINEAR);
436 	vp_reg_writemask(res, VP_MODE, val, VP_MODE_FMT_MASK);
437 
438 	/* setting size of input image */
439 	vp_reg_write(res, VP_IMG_SIZE_Y, VP_IMG_HSIZE(plane->pitch) |
440 		VP_IMG_VSIZE(plane->fb_height));
441 	/* chroma height has to reduced by 2 to avoid chroma distorions */
442 	vp_reg_write(res, VP_IMG_SIZE_C, VP_IMG_HSIZE(plane->pitch) |
443 		VP_IMG_VSIZE(plane->fb_height / 2));
444 
445 	vp_reg_write(res, VP_SRC_WIDTH, plane->src_width);
446 	vp_reg_write(res, VP_SRC_HEIGHT, plane->src_height);
447 	vp_reg_write(res, VP_SRC_H_POSITION,
448 			VP_SRC_H_POSITION_VAL(plane->src_x));
449 	vp_reg_write(res, VP_SRC_V_POSITION, plane->src_y);
450 
451 	vp_reg_write(res, VP_DST_WIDTH, plane->crtc_width);
452 	vp_reg_write(res, VP_DST_H_POSITION, plane->crtc_x);
453 	if (ctx->interlace) {
454 		vp_reg_write(res, VP_DST_HEIGHT, plane->crtc_height / 2);
455 		vp_reg_write(res, VP_DST_V_POSITION, plane->crtc_y / 2);
456 	} else {
457 		vp_reg_write(res, VP_DST_HEIGHT, plane->crtc_height);
458 		vp_reg_write(res, VP_DST_V_POSITION, plane->crtc_y);
459 	}
460 
461 	vp_reg_write(res, VP_H_RATIO, plane->h_ratio);
462 	vp_reg_write(res, VP_V_RATIO, plane->v_ratio);
463 
464 	vp_reg_write(res, VP_ENDIAN_MODE, VP_ENDIAN_MODE_LITTLE);
465 
466 	/* set buffer address to vp */
467 	vp_reg_write(res, VP_TOP_Y_PTR, luma_addr[0]);
468 	vp_reg_write(res, VP_BOT_Y_PTR, luma_addr[1]);
469 	vp_reg_write(res, VP_TOP_C_PTR, chroma_addr[0]);
470 	vp_reg_write(res, VP_BOT_C_PTR, chroma_addr[1]);
471 
472 	mixer_cfg_scan(ctx, plane->mode_height);
473 	mixer_cfg_rgb_fmt(ctx, plane->mode_height);
474 	mixer_cfg_layer(ctx, win, true);
475 	mixer_run(ctx);
476 
477 	mixer_vsync_set_update(ctx, true);
478 	spin_unlock_irqrestore(&res->reg_slock, flags);
479 
480 	mixer_regs_dump(ctx);
481 	vp_regs_dump(ctx);
482 }
483 
484 static void mixer_layer_update(struct mixer_context *ctx)
485 {
486 	struct mixer_resources *res = &ctx->mixer_res;
487 
488 	mixer_reg_writemask(res, MXR_CFG, ~0, MXR_CFG_LAYER_UPDATE);
489 }
490 
491 static int mixer_setup_scale(const struct exynos_drm_plane *plane,
492 		unsigned int *x_ratio, unsigned int *y_ratio)
493 {
494 	if (plane->crtc_width != plane->src_width) {
495 		if (plane->crtc_width == 2 * plane->src_width)
496 			*x_ratio = 1;
497 		else
498 			goto fail;
499 	}
500 
501 	if (plane->crtc_height != plane->src_height) {
502 		if (plane->crtc_height == 2 * plane->src_height)
503 			*y_ratio = 1;
504 		else
505 			goto fail;
506 	}
507 
508 	return 0;
509 
510 fail:
511 	DRM_DEBUG_KMS("only 2x width/height scaling of plane supported\n");
512 	return -ENOTSUPP;
513 }
514 
515 static void mixer_graph_buffer(struct mixer_context *ctx, unsigned int win)
516 {
517 	struct mixer_resources *res = &ctx->mixer_res;
518 	unsigned long flags;
519 	struct exynos_drm_plane *plane;
520 	unsigned int x_ratio = 0, y_ratio = 0;
521 	unsigned int src_x_offset, src_y_offset, dst_x_offset, dst_y_offset;
522 	dma_addr_t dma_addr;
523 	unsigned int fmt;
524 	u32 val;
525 
526 	plane = &ctx->planes[win];
527 
528 	switch (plane->pixel_format) {
529 	case DRM_FORMAT_XRGB4444:
530 		fmt = MXR_FORMAT_ARGB4444;
531 		break;
532 
533 	case DRM_FORMAT_XRGB1555:
534 		fmt = MXR_FORMAT_ARGB1555;
535 		break;
536 
537 	case DRM_FORMAT_RGB565:
538 		fmt = MXR_FORMAT_RGB565;
539 		break;
540 
541 	case DRM_FORMAT_XRGB8888:
542 	case DRM_FORMAT_ARGB8888:
543 		fmt = MXR_FORMAT_ARGB8888;
544 		break;
545 
546 	default:
547 		DRM_DEBUG_KMS("pixelformat unsupported by mixer\n");
548 		return;
549 	}
550 
551 	/* check if mixer supports requested scaling setup */
552 	if (mixer_setup_scale(plane, &x_ratio, &y_ratio))
553 		return;
554 
555 	dst_x_offset = plane->crtc_x;
556 	dst_y_offset = plane->crtc_y;
557 
558 	/* converting dma address base and source offset */
559 	dma_addr = plane->dma_addr[0]
560 		+ (plane->src_x * plane->bpp >> 3)
561 		+ (plane->src_y * plane->pitch);
562 	src_x_offset = 0;
563 	src_y_offset = 0;
564 
565 	if (plane->scan_flag & DRM_MODE_FLAG_INTERLACE)
566 		ctx->interlace = true;
567 	else
568 		ctx->interlace = false;
569 
570 	spin_lock_irqsave(&res->reg_slock, flags);
571 	mixer_vsync_set_update(ctx, false);
572 
573 	/* setup format */
574 	mixer_reg_writemask(res, MXR_GRAPHIC_CFG(win),
575 		MXR_GRP_CFG_FORMAT_VAL(fmt), MXR_GRP_CFG_FORMAT_MASK);
576 
577 	/* setup geometry */
578 	mixer_reg_write(res, MXR_GRAPHIC_SPAN(win),
579 			plane->pitch / (plane->bpp >> 3));
580 
581 	/* setup display size */
582 	if (ctx->mxr_ver == MXR_VER_128_0_0_184 &&
583 		win == MIXER_DEFAULT_WIN) {
584 		val  = MXR_MXR_RES_HEIGHT(plane->mode_height);
585 		val |= MXR_MXR_RES_WIDTH(plane->mode_width);
586 		mixer_reg_write(res, MXR_RESOLUTION, val);
587 	}
588 
589 	val  = MXR_GRP_WH_WIDTH(plane->src_width);
590 	val |= MXR_GRP_WH_HEIGHT(plane->src_height);
591 	val |= MXR_GRP_WH_H_SCALE(x_ratio);
592 	val |= MXR_GRP_WH_V_SCALE(y_ratio);
593 	mixer_reg_write(res, MXR_GRAPHIC_WH(win), val);
594 
595 	/* setup offsets in source image */
596 	val  = MXR_GRP_SXY_SX(src_x_offset);
597 	val |= MXR_GRP_SXY_SY(src_y_offset);
598 	mixer_reg_write(res, MXR_GRAPHIC_SXY(win), val);
599 
600 	/* setup offsets in display image */
601 	val  = MXR_GRP_DXY_DX(dst_x_offset);
602 	val |= MXR_GRP_DXY_DY(dst_y_offset);
603 	mixer_reg_write(res, MXR_GRAPHIC_DXY(win), val);
604 
605 	/* set buffer address to mixer */
606 	mixer_reg_write(res, MXR_GRAPHIC_BASE(win), dma_addr);
607 
608 	mixer_cfg_scan(ctx, plane->mode_height);
609 	mixer_cfg_rgb_fmt(ctx, plane->mode_height);
610 	mixer_cfg_layer(ctx, win, true);
611 
612 	/* layer update mandatory for mixer 16.0.33.0 */
613 	if (ctx->mxr_ver == MXR_VER_16_0_33_0 ||
614 		ctx->mxr_ver == MXR_VER_128_0_0_184)
615 		mixer_layer_update(ctx);
616 
617 	mixer_run(ctx);
618 
619 	mixer_vsync_set_update(ctx, true);
620 	spin_unlock_irqrestore(&res->reg_slock, flags);
621 
622 	mixer_regs_dump(ctx);
623 }
624 
625 static void vp_win_reset(struct mixer_context *ctx)
626 {
627 	struct mixer_resources *res = &ctx->mixer_res;
628 	int tries = 100;
629 
630 	vp_reg_write(res, VP_SRESET, VP_SRESET_PROCESSING);
631 	for (tries = 100; tries; --tries) {
632 		/* waiting until VP_SRESET_PROCESSING is 0 */
633 		if (~vp_reg_read(res, VP_SRESET) & VP_SRESET_PROCESSING)
634 			break;
635 		usleep_range(10000, 12000);
636 	}
637 	WARN(tries == 0, "failed to reset Video Processor\n");
638 }
639 
640 static void mixer_win_reset(struct mixer_context *ctx)
641 {
642 	struct mixer_resources *res = &ctx->mixer_res;
643 	unsigned long flags;
644 	u32 val; /* value stored to register */
645 
646 	spin_lock_irqsave(&res->reg_slock, flags);
647 	mixer_vsync_set_update(ctx, false);
648 
649 	mixer_reg_writemask(res, MXR_CFG, MXR_CFG_DST_HDMI, MXR_CFG_DST_MASK);
650 
651 	/* set output in RGB888 mode */
652 	mixer_reg_writemask(res, MXR_CFG, MXR_CFG_OUT_RGB888, MXR_CFG_OUT_MASK);
653 
654 	/* 16 beat burst in DMA */
655 	mixer_reg_writemask(res, MXR_STATUS, MXR_STATUS_16_BURST,
656 		MXR_STATUS_BURST_MASK);
657 
658 	/* setting default layer priority: layer1 > layer0 > video
659 	 * because typical usage scenario would be
660 	 * layer1 - OSD
661 	 * layer0 - framebuffer
662 	 * video - video overlay
663 	 */
664 	val = MXR_LAYER_CFG_GRP1_VAL(3);
665 	val |= MXR_LAYER_CFG_GRP0_VAL(2);
666 	if (ctx->vp_enabled)
667 		val |= MXR_LAYER_CFG_VP_VAL(1);
668 	mixer_reg_write(res, MXR_LAYER_CFG, val);
669 
670 	/* setting background color */
671 	mixer_reg_write(res, MXR_BG_COLOR0, 0x008080);
672 	mixer_reg_write(res, MXR_BG_COLOR1, 0x008080);
673 	mixer_reg_write(res, MXR_BG_COLOR2, 0x008080);
674 
675 	/* setting graphical layers */
676 	val  = MXR_GRP_CFG_COLOR_KEY_DISABLE; /* no blank key */
677 	val |= MXR_GRP_CFG_WIN_BLEND_EN;
678 	val |= MXR_GRP_CFG_ALPHA_VAL(0xff); /* non-transparent alpha */
679 
680 	/* Don't blend layer 0 onto the mixer background */
681 	mixer_reg_write(res, MXR_GRAPHIC_CFG(0), val);
682 
683 	/* Blend layer 1 into layer 0 */
684 	val |= MXR_GRP_CFG_BLEND_PRE_MUL;
685 	val |= MXR_GRP_CFG_PIXEL_BLEND_EN;
686 	mixer_reg_write(res, MXR_GRAPHIC_CFG(1), val);
687 
688 	/* setting video layers */
689 	val = MXR_GRP_CFG_ALPHA_VAL(0);
690 	mixer_reg_write(res, MXR_VIDEO_CFG, val);
691 
692 	if (ctx->vp_enabled) {
693 		/* configuration of Video Processor Registers */
694 		vp_win_reset(ctx);
695 		vp_default_filter(res);
696 	}
697 
698 	/* disable all layers */
699 	mixer_reg_writemask(res, MXR_CFG, 0, MXR_CFG_GRP0_ENABLE);
700 	mixer_reg_writemask(res, MXR_CFG, 0, MXR_CFG_GRP1_ENABLE);
701 	if (ctx->vp_enabled)
702 		mixer_reg_writemask(res, MXR_CFG, 0, MXR_CFG_VP_ENABLE);
703 
704 	mixer_vsync_set_update(ctx, true);
705 	spin_unlock_irqrestore(&res->reg_slock, flags);
706 }
707 
708 static irqreturn_t mixer_irq_handler(int irq, void *arg)
709 {
710 	struct mixer_context *ctx = arg;
711 	struct mixer_resources *res = &ctx->mixer_res;
712 	u32 val, base, shadow;
713 
714 	spin_lock(&res->reg_slock);
715 
716 	/* read interrupt status for handling and clearing flags for VSYNC */
717 	val = mixer_reg_read(res, MXR_INT_STATUS);
718 
719 	/* handling VSYNC */
720 	if (val & MXR_INT_STATUS_VSYNC) {
721 		/* interlace scan need to check shadow register */
722 		if (ctx->interlace) {
723 			base = mixer_reg_read(res, MXR_GRAPHIC_BASE(0));
724 			shadow = mixer_reg_read(res, MXR_GRAPHIC_BASE_S(0));
725 			if (base != shadow)
726 				goto out;
727 
728 			base = mixer_reg_read(res, MXR_GRAPHIC_BASE(1));
729 			shadow = mixer_reg_read(res, MXR_GRAPHIC_BASE_S(1));
730 			if (base != shadow)
731 				goto out;
732 		}
733 
734 		drm_handle_vblank(ctx->drm_dev, ctx->pipe);
735 		exynos_drm_crtc_finish_pageflip(ctx->drm_dev, ctx->pipe);
736 
737 		/* set wait vsync event to zero and wake up queue. */
738 		if (atomic_read(&ctx->wait_vsync_event)) {
739 			atomic_set(&ctx->wait_vsync_event, 0);
740 			wake_up(&ctx->wait_vsync_queue);
741 		}
742 	}
743 
744 out:
745 	/* clear interrupts */
746 	if (~val & MXR_INT_EN_VSYNC) {
747 		/* vsync interrupt use different bit for read and clear */
748 		val &= ~MXR_INT_EN_VSYNC;
749 		val |= MXR_INT_CLEAR_VSYNC;
750 	}
751 	mixer_reg_write(res, MXR_INT_STATUS, val);
752 
753 	spin_unlock(&res->reg_slock);
754 
755 	return IRQ_HANDLED;
756 }
757 
758 static int mixer_resources_init(struct mixer_context *mixer_ctx)
759 {
760 	struct device *dev = &mixer_ctx->pdev->dev;
761 	struct mixer_resources *mixer_res = &mixer_ctx->mixer_res;
762 	struct resource *res;
763 	int ret;
764 
765 	spin_lock_init(&mixer_res->reg_slock);
766 
767 	mixer_res->mixer = devm_clk_get(dev, "mixer");
768 	if (IS_ERR(mixer_res->mixer)) {
769 		dev_err(dev, "failed to get clock 'mixer'\n");
770 		return -ENODEV;
771 	}
772 
773 	mixer_res->hdmi = devm_clk_get(dev, "hdmi");
774 	if (IS_ERR(mixer_res->hdmi)) {
775 		dev_err(dev, "failed to get clock 'hdmi'\n");
776 		return PTR_ERR(mixer_res->hdmi);
777 	}
778 
779 	mixer_res->sclk_hdmi = devm_clk_get(dev, "sclk_hdmi");
780 	if (IS_ERR(mixer_res->sclk_hdmi)) {
781 		dev_err(dev, "failed to get clock 'sclk_hdmi'\n");
782 		return -ENODEV;
783 	}
784 	res = platform_get_resource(mixer_ctx->pdev, IORESOURCE_MEM, 0);
785 	if (res == NULL) {
786 		dev_err(dev, "get memory resource failed.\n");
787 		return -ENXIO;
788 	}
789 
790 	mixer_res->mixer_regs = devm_ioremap(dev, res->start,
791 							resource_size(res));
792 	if (mixer_res->mixer_regs == NULL) {
793 		dev_err(dev, "register mapping failed.\n");
794 		return -ENXIO;
795 	}
796 
797 	res = platform_get_resource(mixer_ctx->pdev, IORESOURCE_IRQ, 0);
798 	if (res == NULL) {
799 		dev_err(dev, "get interrupt resource failed.\n");
800 		return -ENXIO;
801 	}
802 
803 	ret = devm_request_irq(dev, res->start, mixer_irq_handler,
804 						0, "drm_mixer", mixer_ctx);
805 	if (ret) {
806 		dev_err(dev, "request interrupt failed.\n");
807 		return ret;
808 	}
809 	mixer_res->irq = res->start;
810 
811 	return 0;
812 }
813 
814 static int vp_resources_init(struct mixer_context *mixer_ctx)
815 {
816 	struct device *dev = &mixer_ctx->pdev->dev;
817 	struct mixer_resources *mixer_res = &mixer_ctx->mixer_res;
818 	struct resource *res;
819 
820 	mixer_res->vp = devm_clk_get(dev, "vp");
821 	if (IS_ERR(mixer_res->vp)) {
822 		dev_err(dev, "failed to get clock 'vp'\n");
823 		return -ENODEV;
824 	}
825 
826 	if (mixer_ctx->has_sclk) {
827 		mixer_res->sclk_mixer = devm_clk_get(dev, "sclk_mixer");
828 		if (IS_ERR(mixer_res->sclk_mixer)) {
829 			dev_err(dev, "failed to get clock 'sclk_mixer'\n");
830 			return -ENODEV;
831 		}
832 		mixer_res->mout_mixer = devm_clk_get(dev, "mout_mixer");
833 		if (IS_ERR(mixer_res->mout_mixer)) {
834 			dev_err(dev, "failed to get clock 'mout_mixer'\n");
835 			return -ENODEV;
836 		}
837 
838 		if (mixer_res->sclk_hdmi && mixer_res->mout_mixer)
839 			clk_set_parent(mixer_res->mout_mixer,
840 				       mixer_res->sclk_hdmi);
841 	}
842 
843 	res = platform_get_resource(mixer_ctx->pdev, IORESOURCE_MEM, 1);
844 	if (res == NULL) {
845 		dev_err(dev, "get memory resource failed.\n");
846 		return -ENXIO;
847 	}
848 
849 	mixer_res->vp_regs = devm_ioremap(dev, res->start,
850 							resource_size(res));
851 	if (mixer_res->vp_regs == NULL) {
852 		dev_err(dev, "register mapping failed.\n");
853 		return -ENXIO;
854 	}
855 
856 	return 0;
857 }
858 
859 static int mixer_initialize(struct mixer_context *mixer_ctx,
860 			struct drm_device *drm_dev)
861 {
862 	int ret;
863 	struct exynos_drm_private *priv;
864 	priv = drm_dev->dev_private;
865 
866 	mixer_ctx->drm_dev = drm_dev;
867 	mixer_ctx->pipe = priv->pipe++;
868 
869 	/* acquire resources: regs, irqs, clocks */
870 	ret = mixer_resources_init(mixer_ctx);
871 	if (ret) {
872 		DRM_ERROR("mixer_resources_init failed ret=%d\n", ret);
873 		return ret;
874 	}
875 
876 	if (mixer_ctx->vp_enabled) {
877 		/* acquire vp resources: regs, irqs, clocks */
878 		ret = vp_resources_init(mixer_ctx);
879 		if (ret) {
880 			DRM_ERROR("vp_resources_init failed ret=%d\n", ret);
881 			return ret;
882 		}
883 	}
884 
885 	ret = drm_iommu_attach_device_if_possible(mixer_ctx->crtc, drm_dev,
886 								mixer_ctx->dev);
887 	if (ret)
888 		priv->pipe--;
889 
890 	return ret;
891 }
892 
893 static void mixer_ctx_remove(struct mixer_context *mixer_ctx)
894 {
895 	if (is_drm_iommu_supported(mixer_ctx->drm_dev))
896 		drm_iommu_detach_device(mixer_ctx->drm_dev, mixer_ctx->dev);
897 }
898 
899 static int mixer_enable_vblank(struct exynos_drm_crtc *crtc)
900 {
901 	struct mixer_context *mixer_ctx = crtc->ctx;
902 	struct mixer_resources *res = &mixer_ctx->mixer_res;
903 
904 	if (!mixer_ctx->powered) {
905 		mixer_ctx->int_en |= MXR_INT_EN_VSYNC;
906 		return 0;
907 	}
908 
909 	/* enable vsync interrupt */
910 	mixer_reg_writemask(res, MXR_INT_EN, MXR_INT_EN_VSYNC,
911 			MXR_INT_EN_VSYNC);
912 
913 	return 0;
914 }
915 
916 static void mixer_disable_vblank(struct exynos_drm_crtc *crtc)
917 {
918 	struct mixer_context *mixer_ctx = crtc->ctx;
919 	struct mixer_resources *res = &mixer_ctx->mixer_res;
920 
921 	/* disable vsync interrupt */
922 	mixer_reg_writemask(res, MXR_INT_EN, 0, MXR_INT_EN_VSYNC);
923 }
924 
925 static void mixer_win_commit(struct exynos_drm_crtc *crtc, unsigned int win)
926 {
927 	struct mixer_context *mixer_ctx = crtc->ctx;
928 
929 	DRM_DEBUG_KMS("win: %d\n", win);
930 
931 	mutex_lock(&mixer_ctx->mixer_mutex);
932 	if (!mixer_ctx->powered) {
933 		mutex_unlock(&mixer_ctx->mixer_mutex);
934 		return;
935 	}
936 	mutex_unlock(&mixer_ctx->mixer_mutex);
937 
938 	if (win > 1 && mixer_ctx->vp_enabled)
939 		vp_video_buffer(mixer_ctx, win);
940 	else
941 		mixer_graph_buffer(mixer_ctx, win);
942 }
943 
944 static void mixer_win_disable(struct exynos_drm_crtc *crtc, unsigned int win)
945 {
946 	struct mixer_context *mixer_ctx = crtc->ctx;
947 	struct mixer_resources *res = &mixer_ctx->mixer_res;
948 	unsigned long flags;
949 
950 	DRM_DEBUG_KMS("win: %d\n", win);
951 
952 	mutex_lock(&mixer_ctx->mixer_mutex);
953 	if (!mixer_ctx->powered) {
954 		mutex_unlock(&mixer_ctx->mixer_mutex);
955 		return;
956 	}
957 	mutex_unlock(&mixer_ctx->mixer_mutex);
958 
959 	spin_lock_irqsave(&res->reg_slock, flags);
960 	mixer_vsync_set_update(mixer_ctx, false);
961 
962 	mixer_cfg_layer(mixer_ctx, win, false);
963 
964 	mixer_vsync_set_update(mixer_ctx, true);
965 	spin_unlock_irqrestore(&res->reg_slock, flags);
966 }
967 
968 static void mixer_wait_for_vblank(struct exynos_drm_crtc *crtc)
969 {
970 	struct mixer_context *mixer_ctx = crtc->ctx;
971 	int err;
972 
973 	mutex_lock(&mixer_ctx->mixer_mutex);
974 	if (!mixer_ctx->powered) {
975 		mutex_unlock(&mixer_ctx->mixer_mutex);
976 		return;
977 	}
978 	mutex_unlock(&mixer_ctx->mixer_mutex);
979 
980 	err = drm_vblank_get(mixer_ctx->drm_dev, mixer_ctx->pipe);
981 	if (err < 0) {
982 		DRM_DEBUG_KMS("failed to acquire vblank counter\n");
983 		return;
984 	}
985 
986 	atomic_set(&mixer_ctx->wait_vsync_event, 1);
987 
988 	/*
989 	 * wait for MIXER to signal VSYNC interrupt or return after
990 	 * timeout which is set to 50ms (refresh rate of 20).
991 	 */
992 	if (!wait_event_timeout(mixer_ctx->wait_vsync_queue,
993 				!atomic_read(&mixer_ctx->wait_vsync_event),
994 				HZ/20))
995 		DRM_DEBUG_KMS("vblank wait timed out.\n");
996 
997 	drm_vblank_put(mixer_ctx->drm_dev, mixer_ctx->pipe);
998 }
999 
1000 static void mixer_enable(struct exynos_drm_crtc *crtc)
1001 {
1002 	struct mixer_context *ctx = crtc->ctx;
1003 	struct mixer_resources *res = &ctx->mixer_res;
1004 	int ret;
1005 
1006 	mutex_lock(&ctx->mixer_mutex);
1007 	if (ctx->powered) {
1008 		mutex_unlock(&ctx->mixer_mutex);
1009 		return;
1010 	}
1011 
1012 	mutex_unlock(&ctx->mixer_mutex);
1013 
1014 	pm_runtime_get_sync(ctx->dev);
1015 
1016 	ret = clk_prepare_enable(res->mixer);
1017 	if (ret < 0) {
1018 		DRM_ERROR("Failed to prepare_enable the mixer clk [%d]\n", ret);
1019 		return;
1020 	}
1021 	ret = clk_prepare_enable(res->hdmi);
1022 	if (ret < 0) {
1023 		DRM_ERROR("Failed to prepare_enable the hdmi clk [%d]\n", ret);
1024 		return;
1025 	}
1026 	if (ctx->vp_enabled) {
1027 		ret = clk_prepare_enable(res->vp);
1028 		if (ret < 0) {
1029 			DRM_ERROR("Failed to prepare_enable the vp clk [%d]\n",
1030 				  ret);
1031 			return;
1032 		}
1033 		if (ctx->has_sclk) {
1034 			ret = clk_prepare_enable(res->sclk_mixer);
1035 			if (ret < 0) {
1036 				DRM_ERROR("Failed to prepare_enable the " \
1037 					   "sclk_mixer clk [%d]\n",
1038 					  ret);
1039 				return;
1040 			}
1041 		}
1042 	}
1043 
1044 	mutex_lock(&ctx->mixer_mutex);
1045 	ctx->powered = true;
1046 	mutex_unlock(&ctx->mixer_mutex);
1047 
1048 	mixer_reg_writemask(res, MXR_STATUS, ~0, MXR_STATUS_SOFT_RESET);
1049 
1050 	mixer_reg_write(res, MXR_INT_EN, ctx->int_en);
1051 	mixer_win_reset(ctx);
1052 }
1053 
1054 static void mixer_disable(struct exynos_drm_crtc *crtc)
1055 {
1056 	struct mixer_context *ctx = crtc->ctx;
1057 	struct mixer_resources *res = &ctx->mixer_res;
1058 	int i;
1059 
1060 	mutex_lock(&ctx->mixer_mutex);
1061 	if (!ctx->powered) {
1062 		mutex_unlock(&ctx->mixer_mutex);
1063 		return;
1064 	}
1065 	mutex_unlock(&ctx->mixer_mutex);
1066 
1067 	mixer_stop(ctx);
1068 	mixer_regs_dump(ctx);
1069 
1070 	for (i = 0; i < MIXER_WIN_NR; i++)
1071 		mixer_win_disable(crtc, i);
1072 
1073 	ctx->int_en = mixer_reg_read(res, MXR_INT_EN);
1074 
1075 	mutex_lock(&ctx->mixer_mutex);
1076 	ctx->powered = false;
1077 	mutex_unlock(&ctx->mixer_mutex);
1078 
1079 	clk_disable_unprepare(res->hdmi);
1080 	clk_disable_unprepare(res->mixer);
1081 	if (ctx->vp_enabled) {
1082 		clk_disable_unprepare(res->vp);
1083 		if (ctx->has_sclk)
1084 			clk_disable_unprepare(res->sclk_mixer);
1085 	}
1086 
1087 	pm_runtime_put_sync(ctx->dev);
1088 }
1089 
1090 /* Only valid for Mixer version 16.0.33.0 */
1091 int mixer_check_mode(struct drm_display_mode *mode)
1092 {
1093 	u32 w, h;
1094 
1095 	w = mode->hdisplay;
1096 	h = mode->vdisplay;
1097 
1098 	DRM_DEBUG_KMS("xres=%d, yres=%d, refresh=%d, intl=%d\n",
1099 		mode->hdisplay, mode->vdisplay, mode->vrefresh,
1100 		(mode->flags & DRM_MODE_FLAG_INTERLACE) ? 1 : 0);
1101 
1102 	if ((w >= 464 && w <= 720 && h >= 261 && h <= 576) ||
1103 		(w >= 1024 && w <= 1280 && h >= 576 && h <= 720) ||
1104 		(w >= 1664 && w <= 1920 && h >= 936 && h <= 1080))
1105 		return 0;
1106 
1107 	return -EINVAL;
1108 }
1109 
1110 static const struct exynos_drm_crtc_ops mixer_crtc_ops = {
1111 	.enable			= mixer_enable,
1112 	.disable		= mixer_disable,
1113 	.enable_vblank		= mixer_enable_vblank,
1114 	.disable_vblank		= mixer_disable_vblank,
1115 	.wait_for_vblank	= mixer_wait_for_vblank,
1116 	.win_commit		= mixer_win_commit,
1117 	.win_disable		= mixer_win_disable,
1118 };
1119 
1120 static struct mixer_drv_data exynos5420_mxr_drv_data = {
1121 	.version = MXR_VER_128_0_0_184,
1122 	.is_vp_enabled = 0,
1123 };
1124 
1125 static struct mixer_drv_data exynos5250_mxr_drv_data = {
1126 	.version = MXR_VER_16_0_33_0,
1127 	.is_vp_enabled = 0,
1128 };
1129 
1130 static struct mixer_drv_data exynos4212_mxr_drv_data = {
1131 	.version = MXR_VER_0_0_0_16,
1132 	.is_vp_enabled = 1,
1133 };
1134 
1135 static struct mixer_drv_data exynos4210_mxr_drv_data = {
1136 	.version = MXR_VER_0_0_0_16,
1137 	.is_vp_enabled = 1,
1138 	.has_sclk = 1,
1139 };
1140 
1141 static const struct platform_device_id mixer_driver_types[] = {
1142 	{
1143 		.name		= "s5p-mixer",
1144 		.driver_data	= (unsigned long)&exynos4210_mxr_drv_data,
1145 	}, {
1146 		.name		= "exynos5-mixer",
1147 		.driver_data	= (unsigned long)&exynos5250_mxr_drv_data,
1148 	}, {
1149 		/* end node */
1150 	}
1151 };
1152 
1153 static struct of_device_id mixer_match_types[] = {
1154 	{
1155 		.compatible = "samsung,exynos4210-mixer",
1156 		.data	= &exynos4210_mxr_drv_data,
1157 	}, {
1158 		.compatible = "samsung,exynos4212-mixer",
1159 		.data	= &exynos4212_mxr_drv_data,
1160 	}, {
1161 		.compatible = "samsung,exynos5-mixer",
1162 		.data	= &exynos5250_mxr_drv_data,
1163 	}, {
1164 		.compatible = "samsung,exynos5250-mixer",
1165 		.data	= &exynos5250_mxr_drv_data,
1166 	}, {
1167 		.compatible = "samsung,exynos5420-mixer",
1168 		.data	= &exynos5420_mxr_drv_data,
1169 	}, {
1170 		/* end node */
1171 	}
1172 };
1173 MODULE_DEVICE_TABLE(of, mixer_match_types);
1174 
1175 static int mixer_bind(struct device *dev, struct device *manager, void *data)
1176 {
1177 	struct mixer_context *ctx = dev_get_drvdata(dev);
1178 	struct drm_device *drm_dev = data;
1179 	struct exynos_drm_plane *exynos_plane;
1180 	enum drm_plane_type type;
1181 	unsigned int zpos;
1182 	int ret;
1183 
1184 	ret = mixer_initialize(ctx, drm_dev);
1185 	if (ret)
1186 		return ret;
1187 
1188 	for (zpos = 0; zpos < MIXER_WIN_NR; zpos++) {
1189 		type = (zpos == MIXER_DEFAULT_WIN) ? DRM_PLANE_TYPE_PRIMARY :
1190 						DRM_PLANE_TYPE_OVERLAY;
1191 		ret = exynos_plane_init(drm_dev, &ctx->planes[zpos],
1192 					1 << ctx->pipe, type, zpos);
1193 		if (ret)
1194 			return ret;
1195 	}
1196 
1197 	exynos_plane = &ctx->planes[MIXER_DEFAULT_WIN];
1198 	ctx->crtc = exynos_drm_crtc_create(drm_dev, &exynos_plane->base,
1199 					   ctx->pipe, EXYNOS_DISPLAY_TYPE_HDMI,
1200 					   &mixer_crtc_ops, ctx);
1201 	if (IS_ERR(ctx->crtc)) {
1202 		mixer_ctx_remove(ctx);
1203 		ret = PTR_ERR(ctx->crtc);
1204 		goto free_ctx;
1205 	}
1206 
1207 	return 0;
1208 
1209 free_ctx:
1210 	devm_kfree(dev, ctx);
1211 	return ret;
1212 }
1213 
1214 static void mixer_unbind(struct device *dev, struct device *master, void *data)
1215 {
1216 	struct mixer_context *ctx = dev_get_drvdata(dev);
1217 
1218 	mixer_ctx_remove(ctx);
1219 }
1220 
1221 static const struct component_ops mixer_component_ops = {
1222 	.bind	= mixer_bind,
1223 	.unbind	= mixer_unbind,
1224 };
1225 
1226 static int mixer_probe(struct platform_device *pdev)
1227 {
1228 	struct device *dev = &pdev->dev;
1229 	struct mixer_drv_data *drv;
1230 	struct mixer_context *ctx;
1231 	int ret;
1232 
1233 	ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
1234 	if (!ctx) {
1235 		DRM_ERROR("failed to alloc mixer context.\n");
1236 		return -ENOMEM;
1237 	}
1238 
1239 	mutex_init(&ctx->mixer_mutex);
1240 
1241 	if (dev->of_node) {
1242 		const struct of_device_id *match;
1243 
1244 		match = of_match_node(mixer_match_types, dev->of_node);
1245 		drv = (struct mixer_drv_data *)match->data;
1246 	} else {
1247 		drv = (struct mixer_drv_data *)
1248 			platform_get_device_id(pdev)->driver_data;
1249 	}
1250 
1251 	ctx->pdev = pdev;
1252 	ctx->dev = dev;
1253 	ctx->vp_enabled = drv->is_vp_enabled;
1254 	ctx->has_sclk = drv->has_sclk;
1255 	ctx->mxr_ver = drv->version;
1256 	init_waitqueue_head(&ctx->wait_vsync_queue);
1257 	atomic_set(&ctx->wait_vsync_event, 0);
1258 
1259 	platform_set_drvdata(pdev, ctx);
1260 
1261 	ret = component_add(&pdev->dev, &mixer_component_ops);
1262 	if (!ret)
1263 		pm_runtime_enable(dev);
1264 
1265 	return ret;
1266 }
1267 
1268 static int mixer_remove(struct platform_device *pdev)
1269 {
1270 	pm_runtime_disable(&pdev->dev);
1271 
1272 	component_del(&pdev->dev, &mixer_component_ops);
1273 
1274 	return 0;
1275 }
1276 
1277 struct platform_driver mixer_driver = {
1278 	.driver = {
1279 		.name = "exynos-mixer",
1280 		.owner = THIS_MODULE,
1281 		.of_match_table = mixer_match_types,
1282 	},
1283 	.probe = mixer_probe,
1284 	.remove = mixer_remove,
1285 	.id_table	= mixer_driver_types,
1286 };
1287