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