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