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