]> git.openfabrics.org - ~shefty/rdma-dev.git/blob - drivers/gpu/drm/exynos/exynos_mixer.c
21db89530fc77b603ed45fe6109b6b67059f3430
[~shefty/rdma-dev.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         clk_enable(res->mixer);
876         if (ctx->vp_enabled) {
877                 clk_enable(res->vp);
878                 clk_enable(res->sclk_mixer);
879         }
880
881         mixer_reg_write(res, MXR_INT_EN, ctx->int_en);
882         mixer_win_reset(ctx);
883
884         mixer_window_resume(ctx);
885 }
886
887 static void mixer_poweroff(struct mixer_context *ctx)
888 {
889         struct mixer_resources *res = &ctx->mixer_res;
890
891         DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
892
893         mutex_lock(&ctx->mixer_mutex);
894         if (!ctx->powered)
895                 goto out;
896         mutex_unlock(&ctx->mixer_mutex);
897
898         mixer_window_suspend(ctx);
899
900         ctx->int_en = mixer_reg_read(res, MXR_INT_EN);
901
902         clk_disable(res->mixer);
903         if (ctx->vp_enabled) {
904                 clk_disable(res->vp);
905                 clk_disable(res->sclk_mixer);
906         }
907
908         mutex_lock(&ctx->mixer_mutex);
909         ctx->powered = false;
910
911 out:
912         mutex_unlock(&ctx->mixer_mutex);
913 }
914
915 static void mixer_dpms(void *ctx, int mode)
916 {
917         struct mixer_context *mixer_ctx = ctx;
918
919         DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
920
921         switch (mode) {
922         case DRM_MODE_DPMS_ON:
923                 if (pm_runtime_suspended(mixer_ctx->dev))
924                         pm_runtime_get_sync(mixer_ctx->dev);
925                 break;
926         case DRM_MODE_DPMS_STANDBY:
927         case DRM_MODE_DPMS_SUSPEND:
928         case DRM_MODE_DPMS_OFF:
929                 if (!pm_runtime_suspended(mixer_ctx->dev))
930                         pm_runtime_put_sync(mixer_ctx->dev);
931                 break;
932         default:
933                 DRM_DEBUG_KMS("unknown dpms mode: %d\n", mode);
934                 break;
935         }
936 }
937
938 static struct exynos_mixer_ops mixer_ops = {
939         /* manager */
940         .iommu_on               = mixer_iommu_on,
941         .enable_vblank          = mixer_enable_vblank,
942         .disable_vblank         = mixer_disable_vblank,
943         .wait_for_vblank        = mixer_wait_for_vblank,
944         .dpms                   = mixer_dpms,
945
946         /* overlay */
947         .win_mode_set           = mixer_win_mode_set,
948         .win_commit             = mixer_win_commit,
949         .win_disable            = mixer_win_disable,
950 };
951
952 /* for pageflip event */
953 static void mixer_finish_pageflip(struct drm_device *drm_dev, int crtc)
954 {
955         struct exynos_drm_private *dev_priv = drm_dev->dev_private;
956         struct drm_pending_vblank_event *e, *t;
957         struct timeval now;
958         unsigned long flags;
959
960         spin_lock_irqsave(&drm_dev->event_lock, flags);
961
962         list_for_each_entry_safe(e, t, &dev_priv->pageflip_event_list,
963                         base.link) {
964                 /* if event's pipe isn't same as crtc then ignore it. */
965                 if (crtc != e->pipe)
966                         continue;
967
968                 do_gettimeofday(&now);
969                 e->event.sequence = 0;
970                 e->event.tv_sec = now.tv_sec;
971                 e->event.tv_usec = now.tv_usec;
972
973                 list_move_tail(&e->base.link, &e->base.file_priv->event_list);
974                 wake_up_interruptible(&e->base.file_priv->event_wait);
975                 drm_vblank_put(drm_dev, crtc);
976         }
977
978         spin_unlock_irqrestore(&drm_dev->event_lock, flags);
979 }
980
981 static irqreturn_t mixer_irq_handler(int irq, void *arg)
982 {
983         struct exynos_drm_hdmi_context *drm_hdmi_ctx = arg;
984         struct mixer_context *ctx = drm_hdmi_ctx->ctx;
985         struct mixer_resources *res = &ctx->mixer_res;
986         u32 val, base, shadow;
987
988         spin_lock(&res->reg_slock);
989
990         /* read interrupt status for handling and clearing flags for VSYNC */
991         val = mixer_reg_read(res, MXR_INT_STATUS);
992
993         /* handling VSYNC */
994         if (val & MXR_INT_STATUS_VSYNC) {
995                 /* interlace scan need to check shadow register */
996                 if (ctx->interlace) {
997                         base = mixer_reg_read(res, MXR_GRAPHIC_BASE(0));
998                         shadow = mixer_reg_read(res, MXR_GRAPHIC_BASE_S(0));
999                         if (base != shadow)
1000                                 goto out;
1001
1002                         base = mixer_reg_read(res, MXR_GRAPHIC_BASE(1));
1003                         shadow = mixer_reg_read(res, MXR_GRAPHIC_BASE_S(1));
1004                         if (base != shadow)
1005                                 goto out;
1006                 }
1007
1008                 drm_handle_vblank(drm_hdmi_ctx->drm_dev, ctx->pipe);
1009                 mixer_finish_pageflip(drm_hdmi_ctx->drm_dev, ctx->pipe);
1010
1011                 /* set wait vsync event to zero and wake up queue. */
1012                 if (atomic_read(&ctx->wait_vsync_event)) {
1013                         atomic_set(&ctx->wait_vsync_event, 0);
1014                         DRM_WAKEUP(&ctx->wait_vsync_queue);
1015                 }
1016         }
1017
1018 out:
1019         /* clear interrupts */
1020         if (~val & MXR_INT_EN_VSYNC) {
1021                 /* vsync interrupt use different bit for read and clear */
1022                 val &= ~MXR_INT_EN_VSYNC;
1023                 val |= MXR_INT_CLEAR_VSYNC;
1024         }
1025         mixer_reg_write(res, MXR_INT_STATUS, val);
1026
1027         spin_unlock(&res->reg_slock);
1028
1029         return IRQ_HANDLED;
1030 }
1031
1032 static int __devinit mixer_resources_init(struct exynos_drm_hdmi_context *ctx,
1033                                  struct platform_device *pdev)
1034 {
1035         struct mixer_context *mixer_ctx = ctx->ctx;
1036         struct device *dev = &pdev->dev;
1037         struct mixer_resources *mixer_res = &mixer_ctx->mixer_res;
1038         struct resource *res;
1039         int ret;
1040
1041         spin_lock_init(&mixer_res->reg_slock);
1042
1043         mixer_res->mixer = devm_clk_get(dev, "mixer");
1044         if (IS_ERR_OR_NULL(mixer_res->mixer)) {
1045                 dev_err(dev, "failed to get clock 'mixer'\n");
1046                 return -ENODEV;
1047         }
1048
1049         mixer_res->sclk_hdmi = devm_clk_get(dev, "sclk_hdmi");
1050         if (IS_ERR_OR_NULL(mixer_res->sclk_hdmi)) {
1051                 dev_err(dev, "failed to get clock 'sclk_hdmi'\n");
1052                 return -ENODEV;
1053         }
1054         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1055         if (res == NULL) {
1056                 dev_err(dev, "get memory resource failed.\n");
1057                 return -ENXIO;
1058         }
1059
1060         mixer_res->mixer_regs = devm_ioremap(&pdev->dev, res->start,
1061                                                         resource_size(res));
1062         if (mixer_res->mixer_regs == NULL) {
1063                 dev_err(dev, "register mapping failed.\n");
1064                 return -ENXIO;
1065         }
1066
1067         res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
1068         if (res == NULL) {
1069                 dev_err(dev, "get interrupt resource failed.\n");
1070                 return -ENXIO;
1071         }
1072
1073         ret = devm_request_irq(&pdev->dev, res->start, mixer_irq_handler,
1074                                                         0, "drm_mixer", ctx);
1075         if (ret) {
1076                 dev_err(dev, "request interrupt failed.\n");
1077                 return ret;
1078         }
1079         mixer_res->irq = res->start;
1080
1081         return 0;
1082 }
1083
1084 static int __devinit vp_resources_init(struct exynos_drm_hdmi_context *ctx,
1085                                  struct platform_device *pdev)
1086 {
1087         struct mixer_context *mixer_ctx = ctx->ctx;
1088         struct device *dev = &pdev->dev;
1089         struct mixer_resources *mixer_res = &mixer_ctx->mixer_res;
1090         struct resource *res;
1091
1092         mixer_res->vp = devm_clk_get(dev, "vp");
1093         if (IS_ERR_OR_NULL(mixer_res->vp)) {
1094                 dev_err(dev, "failed to get clock 'vp'\n");
1095                 return -ENODEV;
1096         }
1097         mixer_res->sclk_mixer = devm_clk_get(dev, "sclk_mixer");
1098         if (IS_ERR_OR_NULL(mixer_res->sclk_mixer)) {
1099                 dev_err(dev, "failed to get clock 'sclk_mixer'\n");
1100                 return -ENODEV;
1101         }
1102         mixer_res->sclk_dac = devm_clk_get(dev, "sclk_dac");
1103         if (IS_ERR_OR_NULL(mixer_res->sclk_dac)) {
1104                 dev_err(dev, "failed to get clock 'sclk_dac'\n");
1105                 return -ENODEV;
1106         }
1107
1108         if (mixer_res->sclk_hdmi)
1109                 clk_set_parent(mixer_res->sclk_mixer, mixer_res->sclk_hdmi);
1110
1111         res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
1112         if (res == NULL) {
1113                 dev_err(dev, "get memory resource failed.\n");
1114                 return -ENXIO;
1115         }
1116
1117         mixer_res->vp_regs = devm_ioremap(&pdev->dev, res->start,
1118                                                         resource_size(res));
1119         if (mixer_res->vp_regs == NULL) {
1120                 dev_err(dev, "register mapping failed.\n");
1121                 return -ENXIO;
1122         }
1123
1124         return 0;
1125 }
1126
1127 static struct mixer_drv_data exynos5_mxr_drv_data = {
1128         .version = MXR_VER_16_0_33_0,
1129         .is_vp_enabled = 0,
1130 };
1131
1132 static struct mixer_drv_data exynos4_mxr_drv_data = {
1133         .version = MXR_VER_0_0_0_16,
1134         .is_vp_enabled = 1,
1135 };
1136
1137 static struct platform_device_id mixer_driver_types[] = {
1138         {
1139                 .name           = "s5p-mixer",
1140                 .driver_data    = (unsigned long)&exynos4_mxr_drv_data,
1141         }, {
1142                 .name           = "exynos5-mixer",
1143                 .driver_data    = (unsigned long)&exynos5_mxr_drv_data,
1144         }, {
1145                 /* end node */
1146         }
1147 };
1148
1149 static struct of_device_id mixer_match_types[] = {
1150         {
1151                 .compatible = "samsung,exynos5-mixer",
1152                 .data   = &exynos5_mxr_drv_data,
1153         }, {
1154                 /* end node */
1155         }
1156 };
1157
1158 static int __devinit mixer_probe(struct platform_device *pdev)
1159 {
1160         struct device *dev = &pdev->dev;
1161         struct exynos_drm_hdmi_context *drm_hdmi_ctx;
1162         struct mixer_context *ctx;
1163         struct mixer_drv_data *drv;
1164         int ret;
1165
1166         dev_info(dev, "probe start\n");
1167
1168         drm_hdmi_ctx = devm_kzalloc(&pdev->dev, sizeof(*drm_hdmi_ctx),
1169                                                                 GFP_KERNEL);
1170         if (!drm_hdmi_ctx) {
1171                 DRM_ERROR("failed to allocate common hdmi context.\n");
1172                 return -ENOMEM;
1173         }
1174
1175         ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
1176         if (!ctx) {
1177                 DRM_ERROR("failed to alloc mixer context.\n");
1178                 return -ENOMEM;
1179         }
1180
1181         mutex_init(&ctx->mixer_mutex);
1182
1183         if (dev->of_node) {
1184                 const struct of_device_id *match;
1185                 match = of_match_node(of_match_ptr(mixer_match_types),
1186                                                           pdev->dev.of_node);
1187                 drv = (struct mixer_drv_data *)match->data;
1188         } else {
1189                 drv = (struct mixer_drv_data *)
1190                         platform_get_device_id(pdev)->driver_data;
1191         }
1192
1193         ctx->dev = &pdev->dev;
1194         ctx->parent_ctx = (void *)drm_hdmi_ctx;
1195         drm_hdmi_ctx->ctx = (void *)ctx;
1196         ctx->vp_enabled = drv->is_vp_enabled;
1197         ctx->mxr_ver = drv->version;
1198         DRM_INIT_WAITQUEUE(&ctx->wait_vsync_queue);
1199         atomic_set(&ctx->wait_vsync_event, 0);
1200
1201         platform_set_drvdata(pdev, drm_hdmi_ctx);
1202
1203         /* acquire resources: regs, irqs, clocks */
1204         ret = mixer_resources_init(drm_hdmi_ctx, pdev);
1205         if (ret) {
1206                 DRM_ERROR("mixer_resources_init failed\n");
1207                 goto fail;
1208         }
1209
1210         if (ctx->vp_enabled) {
1211                 /* acquire vp resources: regs, irqs, clocks */
1212                 ret = vp_resources_init(drm_hdmi_ctx, pdev);
1213                 if (ret) {
1214                         DRM_ERROR("vp_resources_init failed\n");
1215                         goto fail;
1216                 }
1217         }
1218
1219         /* attach mixer driver to common hdmi. */
1220         exynos_mixer_drv_attach(drm_hdmi_ctx);
1221
1222         /* register specific callback point to common hdmi. */
1223         exynos_mixer_ops_register(&mixer_ops);
1224
1225         pm_runtime_enable(dev);
1226
1227         return 0;
1228
1229
1230 fail:
1231         dev_info(dev, "probe failed\n");
1232         return ret;
1233 }
1234
1235 static int mixer_remove(struct platform_device *pdev)
1236 {
1237         dev_info(&pdev->dev, "remove successful\n");
1238
1239         pm_runtime_disable(&pdev->dev);
1240
1241         return 0;
1242 }
1243
1244 #ifdef CONFIG_PM_SLEEP
1245 static int mixer_suspend(struct device *dev)
1246 {
1247         struct exynos_drm_hdmi_context *drm_hdmi_ctx = get_mixer_context(dev);
1248         struct mixer_context *ctx = drm_hdmi_ctx->ctx;
1249
1250         DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
1251
1252         if (pm_runtime_suspended(dev)) {
1253                 DRM_DEBUG_KMS("%s : Already suspended\n", __func__);
1254                 return 0;
1255         }
1256
1257         mixer_poweroff(ctx);
1258
1259         return 0;
1260 }
1261
1262 static int mixer_resume(struct device *dev)
1263 {
1264         struct exynos_drm_hdmi_context *drm_hdmi_ctx = get_mixer_context(dev);
1265         struct mixer_context *ctx = drm_hdmi_ctx->ctx;
1266
1267         DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
1268
1269         if (!pm_runtime_suspended(dev)) {
1270                 DRM_DEBUG_KMS("%s : Already resumed\n", __func__);
1271                 return 0;
1272         }
1273
1274         mixer_poweron(ctx);
1275
1276         return 0;
1277 }
1278 #endif
1279
1280 #ifdef CONFIG_PM_RUNTIME
1281 static int mixer_runtime_suspend(struct device *dev)
1282 {
1283         struct exynos_drm_hdmi_context *drm_hdmi_ctx = get_mixer_context(dev);
1284         struct mixer_context *ctx = drm_hdmi_ctx->ctx;
1285
1286         DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
1287
1288         mixer_poweroff(ctx);
1289
1290         return 0;
1291 }
1292
1293 static int mixer_runtime_resume(struct device *dev)
1294 {
1295         struct exynos_drm_hdmi_context *drm_hdmi_ctx = get_mixer_context(dev);
1296         struct mixer_context *ctx = drm_hdmi_ctx->ctx;
1297
1298         DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
1299
1300         mixer_poweron(ctx);
1301
1302         return 0;
1303 }
1304 #endif
1305
1306 static const struct dev_pm_ops mixer_pm_ops = {
1307         SET_SYSTEM_SLEEP_PM_OPS(mixer_suspend, mixer_resume)
1308         SET_RUNTIME_PM_OPS(mixer_runtime_suspend, mixer_runtime_resume, NULL)
1309 };
1310
1311 struct platform_driver mixer_driver = {
1312         .driver = {
1313                 .name = "exynos-mixer",
1314                 .owner = THIS_MODULE,
1315                 .pm = &mixer_pm_ops,
1316                 .of_match_table = mixer_match_types,
1317         },
1318         .probe = mixer_probe,
1319         .remove = __devexit_p(mixer_remove),
1320         .id_table       = mixer_driver_types,
1321 };