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