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