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