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