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