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