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