xref: /openbmc/linux/drivers/gpu/drm/exynos/exynos_mixer.c (revision 840ef8b7cc584a23c4f9d05352f4dbaf8e56e5ab)
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 		usleep_range(10000, 12000);
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 	mutex_lock(&mixer_ctx->mixer_mutex);
780 	if (!mixer_ctx->powered) {
781 		mutex_unlock(&mixer_ctx->mixer_mutex);
782 		return;
783 	}
784 	mutex_unlock(&mixer_ctx->mixer_mutex);
785 
786 	if (win > 1 && mixer_ctx->vp_enabled)
787 		vp_video_buffer(mixer_ctx, win);
788 	else
789 		mixer_graph_buffer(mixer_ctx, win);
790 
791 	mixer_ctx->win_data[win].enabled = true;
792 }
793 
794 static void mixer_win_disable(void *ctx, int win)
795 {
796 	struct mixer_context *mixer_ctx = ctx;
797 	struct mixer_resources *res = &mixer_ctx->mixer_res;
798 	unsigned long flags;
799 
800 	DRM_DEBUG_KMS("[%d] %s, win: %d\n", __LINE__, __func__, win);
801 
802 	mutex_lock(&mixer_ctx->mixer_mutex);
803 	if (!mixer_ctx->powered) {
804 		mutex_unlock(&mixer_ctx->mixer_mutex);
805 		mixer_ctx->win_data[win].resume = false;
806 		return;
807 	}
808 	mutex_unlock(&mixer_ctx->mixer_mutex);
809 
810 	spin_lock_irqsave(&res->reg_slock, flags);
811 	mixer_vsync_set_update(mixer_ctx, false);
812 
813 	mixer_cfg_layer(mixer_ctx, win, false);
814 
815 	mixer_vsync_set_update(mixer_ctx, true);
816 	spin_unlock_irqrestore(&res->reg_slock, flags);
817 
818 	mixer_ctx->win_data[win].enabled = false;
819 }
820 
821 int mixer_check_timing(void *ctx, struct fb_videomode *timing)
822 {
823 	struct mixer_context *mixer_ctx = ctx;
824 	u32 w, h;
825 
826 	w = timing->xres;
827 	h = timing->yres;
828 
829 	DRM_DEBUG_KMS("%s : xres=%d, yres=%d, refresh=%d, intl=%d\n",
830 		__func__, timing->xres, timing->yres,
831 		timing->refresh, (timing->vmode &
832 		FB_VMODE_INTERLACED) ? true : false);
833 
834 	if (mixer_ctx->mxr_ver == MXR_VER_0_0_0_16)
835 		return 0;
836 
837 	if ((w >= 464 && w <= 720 && h >= 261 && h <= 576) ||
838 		(w >= 1024 && w <= 1280 && h >= 576 && h <= 720) ||
839 		(w >= 1664 && w <= 1920 && h >= 936 && h <= 1080))
840 		return 0;
841 
842 	return -EINVAL;
843 }
844 static void mixer_wait_for_vblank(void *ctx)
845 {
846 	struct mixer_context *mixer_ctx = ctx;
847 
848 	mutex_lock(&mixer_ctx->mixer_mutex);
849 	if (!mixer_ctx->powered) {
850 		mutex_unlock(&mixer_ctx->mixer_mutex);
851 		return;
852 	}
853 	mutex_unlock(&mixer_ctx->mixer_mutex);
854 
855 	atomic_set(&mixer_ctx->wait_vsync_event, 1);
856 
857 	/*
858 	 * wait for MIXER to signal VSYNC interrupt or return after
859 	 * timeout which is set to 50ms (refresh rate of 20).
860 	 */
861 	if (!wait_event_timeout(mixer_ctx->wait_vsync_queue,
862 				!atomic_read(&mixer_ctx->wait_vsync_event),
863 				DRM_HZ/20))
864 		DRM_DEBUG_KMS("vblank wait timed out.\n");
865 }
866 
867 static void mixer_window_suspend(struct mixer_context *ctx)
868 {
869 	struct hdmi_win_data *win_data;
870 	int i;
871 
872 	for (i = 0; i < MIXER_WIN_NR; i++) {
873 		win_data = &ctx->win_data[i];
874 		win_data->resume = win_data->enabled;
875 		mixer_win_disable(ctx, i);
876 	}
877 	mixer_wait_for_vblank(ctx);
878 }
879 
880 static void mixer_window_resume(struct mixer_context *ctx)
881 {
882 	struct hdmi_win_data *win_data;
883 	int i;
884 
885 	for (i = 0; i < MIXER_WIN_NR; i++) {
886 		win_data = &ctx->win_data[i];
887 		win_data->enabled = win_data->resume;
888 		win_data->resume = false;
889 	}
890 }
891 
892 static void mixer_poweron(struct mixer_context *ctx)
893 {
894 	struct mixer_resources *res = &ctx->mixer_res;
895 
896 	DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
897 
898 	mutex_lock(&ctx->mixer_mutex);
899 	if (ctx->powered) {
900 		mutex_unlock(&ctx->mixer_mutex);
901 		return;
902 	}
903 	ctx->powered = true;
904 	mutex_unlock(&ctx->mixer_mutex);
905 
906 	clk_enable(res->mixer);
907 	if (ctx->vp_enabled) {
908 		clk_enable(res->vp);
909 		clk_enable(res->sclk_mixer);
910 	}
911 
912 	mixer_reg_write(res, MXR_INT_EN, ctx->int_en);
913 	mixer_win_reset(ctx);
914 
915 	mixer_window_resume(ctx);
916 }
917 
918 static void mixer_poweroff(struct mixer_context *ctx)
919 {
920 	struct mixer_resources *res = &ctx->mixer_res;
921 
922 	DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
923 
924 	mutex_lock(&ctx->mixer_mutex);
925 	if (!ctx->powered)
926 		goto out;
927 	mutex_unlock(&ctx->mixer_mutex);
928 
929 	mixer_window_suspend(ctx);
930 
931 	ctx->int_en = mixer_reg_read(res, MXR_INT_EN);
932 
933 	clk_disable(res->mixer);
934 	if (ctx->vp_enabled) {
935 		clk_disable(res->vp);
936 		clk_disable(res->sclk_mixer);
937 	}
938 
939 	mutex_lock(&ctx->mixer_mutex);
940 	ctx->powered = false;
941 
942 out:
943 	mutex_unlock(&ctx->mixer_mutex);
944 }
945 
946 static void mixer_dpms(void *ctx, int mode)
947 {
948 	struct mixer_context *mixer_ctx = ctx;
949 
950 	DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
951 
952 	switch (mode) {
953 	case DRM_MODE_DPMS_ON:
954 		if (pm_runtime_suspended(mixer_ctx->dev))
955 			pm_runtime_get_sync(mixer_ctx->dev);
956 		break;
957 	case DRM_MODE_DPMS_STANDBY:
958 	case DRM_MODE_DPMS_SUSPEND:
959 	case DRM_MODE_DPMS_OFF:
960 		if (!pm_runtime_suspended(mixer_ctx->dev))
961 			pm_runtime_put_sync(mixer_ctx->dev);
962 		break;
963 	default:
964 		DRM_DEBUG_KMS("unknown dpms mode: %d\n", mode);
965 		break;
966 	}
967 }
968 
969 static struct exynos_mixer_ops mixer_ops = {
970 	/* manager */
971 	.iommu_on		= mixer_iommu_on,
972 	.enable_vblank		= mixer_enable_vblank,
973 	.disable_vblank		= mixer_disable_vblank,
974 	.wait_for_vblank	= mixer_wait_for_vblank,
975 	.dpms			= mixer_dpms,
976 
977 	/* overlay */
978 	.win_mode_set		= mixer_win_mode_set,
979 	.win_commit		= mixer_win_commit,
980 	.win_disable		= mixer_win_disable,
981 
982 	/* display */
983 	.check_timing		= mixer_check_timing,
984 };
985 
986 static irqreturn_t mixer_irq_handler(int irq, void *arg)
987 {
988 	struct exynos_drm_hdmi_context *drm_hdmi_ctx = arg;
989 	struct mixer_context *ctx = drm_hdmi_ctx->ctx;
990 	struct mixer_resources *res = &ctx->mixer_res;
991 	u32 val, base, shadow;
992 
993 	spin_lock(&res->reg_slock);
994 
995 	/* read interrupt status for handling and clearing flags for VSYNC */
996 	val = mixer_reg_read(res, MXR_INT_STATUS);
997 
998 	/* handling VSYNC */
999 	if (val & MXR_INT_STATUS_VSYNC) {
1000 		/* interlace scan need to check shadow register */
1001 		if (ctx->interlace) {
1002 			base = mixer_reg_read(res, MXR_GRAPHIC_BASE(0));
1003 			shadow = mixer_reg_read(res, MXR_GRAPHIC_BASE_S(0));
1004 			if (base != shadow)
1005 				goto out;
1006 
1007 			base = mixer_reg_read(res, MXR_GRAPHIC_BASE(1));
1008 			shadow = mixer_reg_read(res, MXR_GRAPHIC_BASE_S(1));
1009 			if (base != shadow)
1010 				goto out;
1011 		}
1012 
1013 		drm_handle_vblank(drm_hdmi_ctx->drm_dev, ctx->pipe);
1014 		exynos_drm_crtc_finish_pageflip(drm_hdmi_ctx->drm_dev,
1015 				ctx->pipe);
1016 
1017 		/* set wait vsync event to zero and wake up queue. */
1018 		if (atomic_read(&ctx->wait_vsync_event)) {
1019 			atomic_set(&ctx->wait_vsync_event, 0);
1020 			DRM_WAKEUP(&ctx->wait_vsync_queue);
1021 		}
1022 	}
1023 
1024 out:
1025 	/* clear interrupts */
1026 	if (~val & MXR_INT_EN_VSYNC) {
1027 		/* vsync interrupt use different bit for read and clear */
1028 		val &= ~MXR_INT_EN_VSYNC;
1029 		val |= MXR_INT_CLEAR_VSYNC;
1030 	}
1031 	mixer_reg_write(res, MXR_INT_STATUS, val);
1032 
1033 	spin_unlock(&res->reg_slock);
1034 
1035 	return IRQ_HANDLED;
1036 }
1037 
1038 static int mixer_resources_init(struct exynos_drm_hdmi_context *ctx,
1039 				struct platform_device *pdev)
1040 {
1041 	struct mixer_context *mixer_ctx = ctx->ctx;
1042 	struct device *dev = &pdev->dev;
1043 	struct mixer_resources *mixer_res = &mixer_ctx->mixer_res;
1044 	struct resource *res;
1045 	int ret;
1046 
1047 	spin_lock_init(&mixer_res->reg_slock);
1048 
1049 	mixer_res->mixer = devm_clk_get(dev, "mixer");
1050 	if (IS_ERR_OR_NULL(mixer_res->mixer)) {
1051 		dev_err(dev, "failed to get clock 'mixer'\n");
1052 		return -ENODEV;
1053 	}
1054 
1055 	mixer_res->sclk_hdmi = devm_clk_get(dev, "sclk_hdmi");
1056 	if (IS_ERR_OR_NULL(mixer_res->sclk_hdmi)) {
1057 		dev_err(dev, "failed to get clock 'sclk_hdmi'\n");
1058 		return -ENODEV;
1059 	}
1060 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1061 	if (res == NULL) {
1062 		dev_err(dev, "get memory resource failed.\n");
1063 		return -ENXIO;
1064 	}
1065 
1066 	mixer_res->mixer_regs = devm_ioremap(&pdev->dev, res->start,
1067 							resource_size(res));
1068 	if (mixer_res->mixer_regs == NULL) {
1069 		dev_err(dev, "register mapping failed.\n");
1070 		return -ENXIO;
1071 	}
1072 
1073 	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
1074 	if (res == NULL) {
1075 		dev_err(dev, "get interrupt resource failed.\n");
1076 		return -ENXIO;
1077 	}
1078 
1079 	ret = devm_request_irq(&pdev->dev, res->start, mixer_irq_handler,
1080 							0, "drm_mixer", ctx);
1081 	if (ret) {
1082 		dev_err(dev, "request interrupt failed.\n");
1083 		return ret;
1084 	}
1085 	mixer_res->irq = res->start;
1086 
1087 	return 0;
1088 }
1089 
1090 static int vp_resources_init(struct exynos_drm_hdmi_context *ctx,
1091 			     struct platform_device *pdev)
1092 {
1093 	struct mixer_context *mixer_ctx = ctx->ctx;
1094 	struct device *dev = &pdev->dev;
1095 	struct mixer_resources *mixer_res = &mixer_ctx->mixer_res;
1096 	struct resource *res;
1097 
1098 	mixer_res->vp = devm_clk_get(dev, "vp");
1099 	if (IS_ERR_OR_NULL(mixer_res->vp)) {
1100 		dev_err(dev, "failed to get clock 'vp'\n");
1101 		return -ENODEV;
1102 	}
1103 	mixer_res->sclk_mixer = devm_clk_get(dev, "sclk_mixer");
1104 	if (IS_ERR_OR_NULL(mixer_res->sclk_mixer)) {
1105 		dev_err(dev, "failed to get clock 'sclk_mixer'\n");
1106 		return -ENODEV;
1107 	}
1108 	mixer_res->sclk_dac = devm_clk_get(dev, "sclk_dac");
1109 	if (IS_ERR_OR_NULL(mixer_res->sclk_dac)) {
1110 		dev_err(dev, "failed to get clock 'sclk_dac'\n");
1111 		return -ENODEV;
1112 	}
1113 
1114 	if (mixer_res->sclk_hdmi)
1115 		clk_set_parent(mixer_res->sclk_mixer, mixer_res->sclk_hdmi);
1116 
1117 	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
1118 	if (res == NULL) {
1119 		dev_err(dev, "get memory resource failed.\n");
1120 		return -ENXIO;
1121 	}
1122 
1123 	mixer_res->vp_regs = devm_ioremap(&pdev->dev, res->start,
1124 							resource_size(res));
1125 	if (mixer_res->vp_regs == NULL) {
1126 		dev_err(dev, "register mapping failed.\n");
1127 		return -ENXIO;
1128 	}
1129 
1130 	return 0;
1131 }
1132 
1133 static struct mixer_drv_data exynos5_mxr_drv_data = {
1134 	.version = MXR_VER_16_0_33_0,
1135 	.is_vp_enabled = 0,
1136 };
1137 
1138 static struct mixer_drv_data exynos4_mxr_drv_data = {
1139 	.version = MXR_VER_0_0_0_16,
1140 	.is_vp_enabled = 1,
1141 };
1142 
1143 static struct platform_device_id mixer_driver_types[] = {
1144 	{
1145 		.name		= "s5p-mixer",
1146 		.driver_data	= (unsigned long)&exynos4_mxr_drv_data,
1147 	}, {
1148 		.name		= "exynos5-mixer",
1149 		.driver_data	= (unsigned long)&exynos5_mxr_drv_data,
1150 	}, {
1151 		/* end node */
1152 	}
1153 };
1154 
1155 static struct of_device_id mixer_match_types[] = {
1156 	{
1157 		.compatible = "samsung,exynos5-mixer",
1158 		.data	= &exynos5_mxr_drv_data,
1159 	}, {
1160 		/* end node */
1161 	}
1162 };
1163 
1164 static int mixer_probe(struct platform_device *pdev)
1165 {
1166 	struct device *dev = &pdev->dev;
1167 	struct exynos_drm_hdmi_context *drm_hdmi_ctx;
1168 	struct mixer_context *ctx;
1169 	struct mixer_drv_data *drv;
1170 	int ret;
1171 
1172 	dev_info(dev, "probe start\n");
1173 
1174 	drm_hdmi_ctx = devm_kzalloc(&pdev->dev, sizeof(*drm_hdmi_ctx),
1175 								GFP_KERNEL);
1176 	if (!drm_hdmi_ctx) {
1177 		DRM_ERROR("failed to allocate common hdmi context.\n");
1178 		return -ENOMEM;
1179 	}
1180 
1181 	ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
1182 	if (!ctx) {
1183 		DRM_ERROR("failed to alloc mixer context.\n");
1184 		return -ENOMEM;
1185 	}
1186 
1187 	mutex_init(&ctx->mixer_mutex);
1188 
1189 	if (dev->of_node) {
1190 		const struct of_device_id *match;
1191 		match = of_match_node(of_match_ptr(mixer_match_types),
1192 							  pdev->dev.of_node);
1193 		drv = (struct mixer_drv_data *)match->data;
1194 	} else {
1195 		drv = (struct mixer_drv_data *)
1196 			platform_get_device_id(pdev)->driver_data;
1197 	}
1198 
1199 	ctx->dev = &pdev->dev;
1200 	ctx->parent_ctx = (void *)drm_hdmi_ctx;
1201 	drm_hdmi_ctx->ctx = (void *)ctx;
1202 	ctx->vp_enabled = drv->is_vp_enabled;
1203 	ctx->mxr_ver = drv->version;
1204 	DRM_INIT_WAITQUEUE(&ctx->wait_vsync_queue);
1205 	atomic_set(&ctx->wait_vsync_event, 0);
1206 
1207 	platform_set_drvdata(pdev, drm_hdmi_ctx);
1208 
1209 	/* acquire resources: regs, irqs, clocks */
1210 	ret = mixer_resources_init(drm_hdmi_ctx, pdev);
1211 	if (ret) {
1212 		DRM_ERROR("mixer_resources_init failed\n");
1213 		goto fail;
1214 	}
1215 
1216 	if (ctx->vp_enabled) {
1217 		/* acquire vp resources: regs, irqs, clocks */
1218 		ret = vp_resources_init(drm_hdmi_ctx, pdev);
1219 		if (ret) {
1220 			DRM_ERROR("vp_resources_init failed\n");
1221 			goto fail;
1222 		}
1223 	}
1224 
1225 	/* attach mixer driver to common hdmi. */
1226 	exynos_mixer_drv_attach(drm_hdmi_ctx);
1227 
1228 	/* register specific callback point to common hdmi. */
1229 	exynos_mixer_ops_register(&mixer_ops);
1230 
1231 	pm_runtime_enable(dev);
1232 
1233 	return 0;
1234 
1235 
1236 fail:
1237 	dev_info(dev, "probe failed\n");
1238 	return ret;
1239 }
1240 
1241 static int mixer_remove(struct platform_device *pdev)
1242 {
1243 	dev_info(&pdev->dev, "remove successful\n");
1244 
1245 	pm_runtime_disable(&pdev->dev);
1246 
1247 	return 0;
1248 }
1249 
1250 #ifdef CONFIG_PM_SLEEP
1251 static int mixer_suspend(struct device *dev)
1252 {
1253 	struct exynos_drm_hdmi_context *drm_hdmi_ctx = get_mixer_context(dev);
1254 	struct mixer_context *ctx = drm_hdmi_ctx->ctx;
1255 
1256 	DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
1257 
1258 	if (pm_runtime_suspended(dev)) {
1259 		DRM_DEBUG_KMS("%s : Already suspended\n", __func__);
1260 		return 0;
1261 	}
1262 
1263 	mixer_poweroff(ctx);
1264 
1265 	return 0;
1266 }
1267 
1268 static int mixer_resume(struct device *dev)
1269 {
1270 	struct exynos_drm_hdmi_context *drm_hdmi_ctx = get_mixer_context(dev);
1271 	struct mixer_context *ctx = drm_hdmi_ctx->ctx;
1272 
1273 	DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
1274 
1275 	if (!pm_runtime_suspended(dev)) {
1276 		DRM_DEBUG_KMS("%s : Already resumed\n", __func__);
1277 		return 0;
1278 	}
1279 
1280 	mixer_poweron(ctx);
1281 
1282 	return 0;
1283 }
1284 #endif
1285 
1286 #ifdef CONFIG_PM_RUNTIME
1287 static int mixer_runtime_suspend(struct device *dev)
1288 {
1289 	struct exynos_drm_hdmi_context *drm_hdmi_ctx = get_mixer_context(dev);
1290 	struct mixer_context *ctx = drm_hdmi_ctx->ctx;
1291 
1292 	DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
1293 
1294 	mixer_poweroff(ctx);
1295 
1296 	return 0;
1297 }
1298 
1299 static int mixer_runtime_resume(struct device *dev)
1300 {
1301 	struct exynos_drm_hdmi_context *drm_hdmi_ctx = get_mixer_context(dev);
1302 	struct mixer_context *ctx = drm_hdmi_ctx->ctx;
1303 
1304 	DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
1305 
1306 	mixer_poweron(ctx);
1307 
1308 	return 0;
1309 }
1310 #endif
1311 
1312 static const struct dev_pm_ops mixer_pm_ops = {
1313 	SET_SYSTEM_SLEEP_PM_OPS(mixer_suspend, mixer_resume)
1314 	SET_RUNTIME_PM_OPS(mixer_runtime_suspend, mixer_runtime_resume, NULL)
1315 };
1316 
1317 struct platform_driver mixer_driver = {
1318 	.driver = {
1319 		.name = "exynos-mixer",
1320 		.owner = THIS_MODULE,
1321 		.pm = &mixer_pm_ops,
1322 		.of_match_table = mixer_match_types,
1323 	},
1324 	.probe = mixer_probe,
1325 	.remove = mixer_remove,
1326 	.id_table	= mixer_driver_types,
1327 };
1328