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