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