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