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