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