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