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