]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/gpu/drm/exynos/exynos_mixer.c
drm/exynos: hdmi: enable exynos 4210 and 4x12 soc support
[karo-tx-linux.git] / drivers / gpu / drm / exynos / exynos_mixer.c
1 /*
2  * Copyright (C) 2011 Samsung Electronics Co.Ltd
3  * Authors:
4  * Seung-Woo Kim <sw0312.kim@samsung.com>
5  *      Inki Dae <inki.dae@samsung.com>
6  *      Joonyoung Shim <jy0922.shim@samsung.com>
7  *
8  * Based on drivers/media/video/s5p-tv/mixer_reg.c
9  *
10  * This program is free software; you can redistribute  it and/or modify it
11  * under  the terms of  the GNU General  Public License as published by the
12  * Free Software Foundation;  either version 2 of the  License, or (at your
13  * option) any later version.
14  *
15  */
16
17 #include <drm/drmP.h>
18
19 #include "regs-mixer.h"
20 #include "regs-vp.h"
21
22 #include <linux/kernel.h>
23 #include <linux/spinlock.h>
24 #include <linux/wait.h>
25 #include <linux/i2c.h>
26 #include <linux/platform_device.h>
27 #include <linux/interrupt.h>
28 #include <linux/irq.h>
29 #include <linux/delay.h>
30 #include <linux/pm_runtime.h>
31 #include <linux/clk.h>
32 #include <linux/regulator/consumer.h>
33 #include <linux/of.h>
34 #include <linux/component.h>
35
36 #include <drm/exynos_drm.h>
37
38 #include "exynos_drm_drv.h"
39 #include "exynos_drm_crtc.h"
40 #include "exynos_drm_iommu.h"
41 #include "exynos_mixer.h"
42
43 #define get_mixer_manager(dev)  platform_get_drvdata(to_platform_device(dev))
44
45 #define MIXER_WIN_NR            3
46 #define MIXER_DEFAULT_WIN       0
47
48 struct hdmi_win_data {
49         dma_addr_t              dma_addr;
50         dma_addr_t              chroma_dma_addr;
51         uint32_t                pixel_format;
52         unsigned int            bpp;
53         unsigned int            crtc_x;
54         unsigned int            crtc_y;
55         unsigned int            crtc_width;
56         unsigned int            crtc_height;
57         unsigned int            fb_x;
58         unsigned int            fb_y;
59         unsigned int            fb_width;
60         unsigned int            fb_height;
61         unsigned int            src_width;
62         unsigned int            src_height;
63         unsigned int            mode_width;
64         unsigned int            mode_height;
65         unsigned int            scan_flags;
66         bool                    enabled;
67         bool                    resume;
68 };
69
70 struct mixer_resources {
71         int                     irq;
72         void __iomem            *mixer_regs;
73         void __iomem            *vp_regs;
74         spinlock_t              reg_slock;
75         struct clk              *mixer;
76         struct clk              *vp;
77         struct clk              *sclk_mixer;
78         struct clk              *sclk_hdmi;
79         struct clk              *mout_mixer;
80 };
81
82 enum mixer_version_id {
83         MXR_VER_0_0_0_16,
84         MXR_VER_16_0_33_0,
85         MXR_VER_128_0_0_184,
86 };
87
88 struct mixer_context {
89         struct platform_device *pdev;
90         struct device           *dev;
91         struct drm_device       *drm_dev;
92         int                     pipe;
93         bool                    interlace;
94         bool                    powered;
95         bool                    vp_enabled;
96         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                 break;
370         }
371 }
372
373 static void mixer_run(struct mixer_context *ctx)
374 {
375         struct mixer_resources *res = &ctx->mixer_res;
376
377         mixer_reg_writemask(res, MXR_STATUS, ~0, MXR_STATUS_REG_RUN);
378
379         mixer_regs_dump(ctx);
380 }
381
382 static void mixer_stop(struct mixer_context *ctx)
383 {
384         struct mixer_resources *res = &ctx->mixer_res;
385         int timeout = 20;
386
387         mixer_reg_writemask(res, MXR_STATUS, 0, MXR_STATUS_REG_RUN);
388
389         while (!(mixer_reg_read(res, MXR_STATUS) & MXR_STATUS_REG_IDLE) &&
390                         --timeout)
391                 usleep_range(10000, 12000);
392
393         mixer_regs_dump(ctx);
394 }
395
396 static void vp_video_buffer(struct mixer_context *ctx, int win)
397 {
398         struct mixer_resources *res = &ctx->mixer_res;
399         unsigned long flags;
400         struct hdmi_win_data *win_data;
401         unsigned int x_ratio, y_ratio;
402         unsigned int buf_num = 1;
403         dma_addr_t luma_addr[2], chroma_addr[2];
404         bool tiled_mode = false;
405         bool crcb_mode = false;
406         u32 val;
407
408         win_data = &ctx->win_data[win];
409
410         switch (win_data->pixel_format) {
411         case DRM_FORMAT_NV12MT:
412                 tiled_mode = true;
413         case DRM_FORMAT_NV12:
414                 crcb_mode = false;
415                 buf_num = 2;
416                 break;
417         /* TODO: single buffer format NV12, NV21 */
418         default:
419                 /* ignore pixel format at disable time */
420                 if (!win_data->dma_addr)
421                         break;
422
423                 DRM_ERROR("pixel format for vp is wrong [%d].\n",
424                                 win_data->pixel_format);
425                 return;
426         }
427
428         /* scaling feature: (src << 16) / dst */
429         x_ratio = (win_data->src_width << 16) / win_data->crtc_width;
430         y_ratio = (win_data->src_height << 16) / win_data->crtc_height;
431
432         if (buf_num == 2) {
433                 luma_addr[0] = win_data->dma_addr;
434                 chroma_addr[0] = win_data->chroma_dma_addr;
435         } else {
436                 luma_addr[0] = win_data->dma_addr;
437                 chroma_addr[0] = win_data->dma_addr
438                         + (win_data->fb_width * win_data->fb_height);
439         }
440
441         if (win_data->scan_flags & DRM_MODE_FLAG_INTERLACE) {
442                 ctx->interlace = true;
443                 if (tiled_mode) {
444                         luma_addr[1] = luma_addr[0] + 0x40;
445                         chroma_addr[1] = chroma_addr[0] + 0x40;
446                 } else {
447                         luma_addr[1] = luma_addr[0] + win_data->fb_width;
448                         chroma_addr[1] = chroma_addr[0] + win_data->fb_width;
449                 }
450         } else {
451                 ctx->interlace = false;
452                 luma_addr[1] = 0;
453                 chroma_addr[1] = 0;
454         }
455
456         spin_lock_irqsave(&res->reg_slock, flags);
457         mixer_vsync_set_update(ctx, false);
458
459         /* interlace or progressive scan mode */
460         val = (ctx->interlace ? ~0 : 0);
461         vp_reg_writemask(res, VP_MODE, val, VP_MODE_LINE_SKIP);
462
463         /* setup format */
464         val = (crcb_mode ? VP_MODE_NV21 : VP_MODE_NV12);
465         val |= (tiled_mode ? VP_MODE_MEM_TILED : VP_MODE_MEM_LINEAR);
466         vp_reg_writemask(res, VP_MODE, val, VP_MODE_FMT_MASK);
467
468         /* setting size of input image */
469         vp_reg_write(res, VP_IMG_SIZE_Y, VP_IMG_HSIZE(win_data->fb_width) |
470                 VP_IMG_VSIZE(win_data->fb_height));
471         /* chroma height has to reduced by 2 to avoid chroma distorions */
472         vp_reg_write(res, VP_IMG_SIZE_C, VP_IMG_HSIZE(win_data->fb_width) |
473                 VP_IMG_VSIZE(win_data->fb_height / 2));
474
475         vp_reg_write(res, VP_SRC_WIDTH, win_data->src_width);
476         vp_reg_write(res, VP_SRC_HEIGHT, win_data->src_height);
477         vp_reg_write(res, VP_SRC_H_POSITION,
478                         VP_SRC_H_POSITION_VAL(win_data->fb_x));
479         vp_reg_write(res, VP_SRC_V_POSITION, win_data->fb_y);
480
481         vp_reg_write(res, VP_DST_WIDTH, win_data->crtc_width);
482         vp_reg_write(res, VP_DST_H_POSITION, win_data->crtc_x);
483         if (ctx->interlace) {
484                 vp_reg_write(res, VP_DST_HEIGHT, win_data->crtc_height / 2);
485                 vp_reg_write(res, VP_DST_V_POSITION, win_data->crtc_y / 2);
486         } else {
487                 vp_reg_write(res, VP_DST_HEIGHT, win_data->crtc_height);
488                 vp_reg_write(res, VP_DST_V_POSITION, win_data->crtc_y);
489         }
490
491         vp_reg_write(res, VP_H_RATIO, x_ratio);
492         vp_reg_write(res, VP_V_RATIO, y_ratio);
493
494         vp_reg_write(res, VP_ENDIAN_MODE, VP_ENDIAN_MODE_LITTLE);
495
496         /* set buffer address to vp */
497         vp_reg_write(res, VP_TOP_Y_PTR, luma_addr[0]);
498         vp_reg_write(res, VP_BOT_Y_PTR, luma_addr[1]);
499         vp_reg_write(res, VP_TOP_C_PTR, chroma_addr[0]);
500         vp_reg_write(res, VP_BOT_C_PTR, chroma_addr[1]);
501
502         mixer_cfg_scan(ctx, win_data->mode_height);
503         mixer_cfg_rgb_fmt(ctx, win_data->mode_height);
504         mixer_cfg_layer(ctx, win, true);
505         mixer_run(ctx);
506
507         mixer_vsync_set_update(ctx, true);
508         spin_unlock_irqrestore(&res->reg_slock, flags);
509
510         vp_regs_dump(ctx);
511 }
512
513 static void mixer_layer_update(struct mixer_context *ctx)
514 {
515         struct mixer_resources *res = &ctx->mixer_res;
516
517         mixer_reg_writemask(res, MXR_CFG, ~0, MXR_CFG_LAYER_UPDATE);
518 }
519
520 static void mixer_graph_buffer(struct mixer_context *ctx, int win)
521 {
522         struct mixer_resources *res = &ctx->mixer_res;
523         unsigned long flags;
524         struct hdmi_win_data *win_data;
525         unsigned int x_ratio, y_ratio;
526         unsigned int src_x_offset, src_y_offset, dst_x_offset, dst_y_offset;
527         dma_addr_t dma_addr;
528         unsigned int fmt;
529         u32 val;
530
531         win_data = &ctx->win_data[win];
532
533         #define RGB565 4
534         #define ARGB1555 5
535         #define ARGB4444 6
536         #define ARGB8888 7
537
538         switch (win_data->bpp) {
539         case 16:
540                 fmt = ARGB4444;
541                 break;
542         case 32:
543                 fmt = ARGB8888;
544                 break;
545         default:
546                 fmt = ARGB8888;
547         }
548
549         /* 2x scaling feature */
550         x_ratio = 0;
551         y_ratio = 0;
552
553         dst_x_offset = win_data->crtc_x;
554         dst_y_offset = win_data->crtc_y;
555
556         /* converting dma address base and source offset */
557         dma_addr = win_data->dma_addr
558                 + (win_data->fb_x * win_data->bpp >> 3)
559                 + (win_data->fb_y * win_data->fb_width * win_data->bpp >> 3);
560         src_x_offset = 0;
561         src_y_offset = 0;
562
563         if (win_data->scan_flags & DRM_MODE_FLAG_INTERLACE)
564                 ctx->interlace = true;
565         else
566                 ctx->interlace = false;
567
568         spin_lock_irqsave(&res->reg_slock, flags);
569         mixer_vsync_set_update(ctx, false);
570
571         /* setup format */
572         mixer_reg_writemask(res, MXR_GRAPHIC_CFG(win),
573                 MXR_GRP_CFG_FORMAT_VAL(fmt), MXR_GRP_CFG_FORMAT_MASK);
574
575         /* setup geometry */
576         mixer_reg_write(res, MXR_GRAPHIC_SPAN(win), win_data->fb_width);
577
578         /* setup display size */
579         if (ctx->mxr_ver == MXR_VER_128_0_0_184 &&
580                 win == MIXER_DEFAULT_WIN) {
581                 val  = MXR_MXR_RES_HEIGHT(win_data->fb_height);
582                 val |= MXR_MXR_RES_WIDTH(win_data->fb_width);
583                 mixer_reg_write(res, MXR_RESOLUTION, val);
584         }
585
586         val  = MXR_GRP_WH_WIDTH(win_data->crtc_width);
587         val |= MXR_GRP_WH_HEIGHT(win_data->crtc_height);
588         val |= MXR_GRP_WH_H_SCALE(x_ratio);
589         val |= MXR_GRP_WH_V_SCALE(y_ratio);
590         mixer_reg_write(res, MXR_GRAPHIC_WH(win), val);
591
592         /* setup offsets in source image */
593         val  = MXR_GRP_SXY_SX(src_x_offset);
594         val |= MXR_GRP_SXY_SY(src_y_offset);
595         mixer_reg_write(res, MXR_GRAPHIC_SXY(win), val);
596
597         /* setup offsets in display image */
598         val  = MXR_GRP_DXY_DX(dst_x_offset);
599         val |= MXR_GRP_DXY_DY(dst_y_offset);
600         mixer_reg_write(res, MXR_GRAPHIC_DXY(win), val);
601
602         /* set buffer address to mixer */
603         mixer_reg_write(res, MXR_GRAPHIC_BASE(win), dma_addr);
604
605         mixer_cfg_scan(ctx, win_data->mode_height);
606         mixer_cfg_rgb_fmt(ctx, win_data->mode_height);
607         mixer_cfg_layer(ctx, win, true);
608
609         /* layer update mandatory for mixer 16.0.33.0 */
610         if (ctx->mxr_ver == MXR_VER_16_0_33_0 ||
611                 ctx->mxr_ver == MXR_VER_128_0_0_184)
612                 mixer_layer_update(ctx);
613
614         mixer_run(ctx);
615
616         mixer_vsync_set_update(ctx, true);
617         spin_unlock_irqrestore(&res->reg_slock, flags);
618 }
619
620 static void vp_win_reset(struct mixer_context *ctx)
621 {
622         struct mixer_resources *res = &ctx->mixer_res;
623         int tries = 100;
624
625         vp_reg_write(res, VP_SRESET, VP_SRESET_PROCESSING);
626         for (tries = 100; tries; --tries) {
627                 /* waiting until VP_SRESET_PROCESSING is 0 */
628                 if (~vp_reg_read(res, VP_SRESET) & VP_SRESET_PROCESSING)
629                         break;
630                 usleep_range(10000, 12000);
631         }
632         WARN(tries == 0, "failed to reset Video Processor\n");
633 }
634
635 static void mixer_win_reset(struct mixer_context *ctx)
636 {
637         struct mixer_resources *res = &ctx->mixer_res;
638         unsigned long flags;
639         u32 val; /* value stored to register */
640
641         spin_lock_irqsave(&res->reg_slock, flags);
642         mixer_vsync_set_update(ctx, false);
643
644         mixer_reg_writemask(res, MXR_CFG, MXR_CFG_DST_HDMI, MXR_CFG_DST_MASK);
645
646         /* set output in RGB888 mode */
647         mixer_reg_writemask(res, MXR_CFG, MXR_CFG_OUT_RGB888, MXR_CFG_OUT_MASK);
648
649         /* 16 beat burst in DMA */
650         mixer_reg_writemask(res, MXR_STATUS, MXR_STATUS_16_BURST,
651                 MXR_STATUS_BURST_MASK);
652
653         /* setting default layer priority: layer1 > layer0 > video
654          * because typical usage scenario would be
655          * layer1 - OSD
656          * layer0 - framebuffer
657          * video - video overlay
658          */
659         val = MXR_LAYER_CFG_GRP1_VAL(3);
660         val |= MXR_LAYER_CFG_GRP0_VAL(2);
661         if (ctx->vp_enabled)
662                 val |= MXR_LAYER_CFG_VP_VAL(1);
663         mixer_reg_write(res, MXR_LAYER_CFG, val);
664
665         /* setting background color */
666         mixer_reg_write(res, MXR_BG_COLOR0, 0x008080);
667         mixer_reg_write(res, MXR_BG_COLOR1, 0x008080);
668         mixer_reg_write(res, MXR_BG_COLOR2, 0x008080);
669
670         /* setting graphical layers */
671         val  = MXR_GRP_CFG_COLOR_KEY_DISABLE; /* no blank key */
672         val |= MXR_GRP_CFG_WIN_BLEND_EN;
673         val |= MXR_GRP_CFG_ALPHA_VAL(0xff); /* non-transparent alpha */
674
675         /* Don't blend layer 0 onto the mixer background */
676         mixer_reg_write(res, MXR_GRAPHIC_CFG(0), val);
677
678         /* Blend layer 1 into layer 0 */
679         val |= MXR_GRP_CFG_BLEND_PRE_MUL;
680         val |= MXR_GRP_CFG_PIXEL_BLEND_EN;
681         mixer_reg_write(res, MXR_GRAPHIC_CFG(1), val);
682
683         /* setting video layers */
684         val = MXR_GRP_CFG_ALPHA_VAL(0);
685         mixer_reg_write(res, MXR_VIDEO_CFG, val);
686
687         if (ctx->vp_enabled) {
688                 /* configuration of Video Processor Registers */
689                 vp_win_reset(ctx);
690                 vp_default_filter(res);
691         }
692
693         /* disable all layers */
694         mixer_reg_writemask(res, MXR_CFG, 0, MXR_CFG_GRP0_ENABLE);
695         mixer_reg_writemask(res, MXR_CFG, 0, MXR_CFG_GRP1_ENABLE);
696         if (ctx->vp_enabled)
697                 mixer_reg_writemask(res, MXR_CFG, 0, MXR_CFG_VP_ENABLE);
698
699         mixer_vsync_set_update(ctx, true);
700         spin_unlock_irqrestore(&res->reg_slock, flags);
701 }
702
703 static irqreturn_t mixer_irq_handler(int irq, void *arg)
704 {
705         struct mixer_context *ctx = arg;
706         struct mixer_resources *res = &ctx->mixer_res;
707         u32 val, base, shadow;
708
709         spin_lock(&res->reg_slock);
710
711         /* read interrupt status for handling and clearing flags for VSYNC */
712         val = mixer_reg_read(res, MXR_INT_STATUS);
713
714         /* handling VSYNC */
715         if (val & MXR_INT_STATUS_VSYNC) {
716                 /* interlace scan need to check shadow register */
717                 if (ctx->interlace) {
718                         base = mixer_reg_read(res, MXR_GRAPHIC_BASE(0));
719                         shadow = mixer_reg_read(res, MXR_GRAPHIC_BASE_S(0));
720                         if (base != shadow)
721                                 goto out;
722
723                         base = mixer_reg_read(res, MXR_GRAPHIC_BASE(1));
724                         shadow = mixer_reg_read(res, MXR_GRAPHIC_BASE_S(1));
725                         if (base != shadow)
726                                 goto out;
727                 }
728
729                 drm_handle_vblank(ctx->drm_dev, ctx->pipe);
730                 exynos_drm_crtc_finish_pageflip(ctx->drm_dev, ctx->pipe);
731
732                 /* set wait vsync event to zero and wake up queue. */
733                 if (atomic_read(&ctx->wait_vsync_event)) {
734                         atomic_set(&ctx->wait_vsync_event, 0);
735                         wake_up(&ctx->wait_vsync_queue);
736                 }
737         }
738
739 out:
740         /* clear interrupts */
741         if (~val & MXR_INT_EN_VSYNC) {
742                 /* vsync interrupt use different bit for read and clear */
743                 val &= ~MXR_INT_EN_VSYNC;
744                 val |= MXR_INT_CLEAR_VSYNC;
745         }
746         mixer_reg_write(res, MXR_INT_STATUS, val);
747
748         spin_unlock(&res->reg_slock);
749
750         return IRQ_HANDLED;
751 }
752
753 static int mixer_resources_init(struct mixer_context *mixer_ctx)
754 {
755         struct device *dev = &mixer_ctx->pdev->dev;
756         struct mixer_resources *mixer_res = &mixer_ctx->mixer_res;
757         struct resource *res;
758         int ret;
759
760         spin_lock_init(&mixer_res->reg_slock);
761
762         mixer_res->mixer = devm_clk_get(dev, "mixer");
763         if (IS_ERR(mixer_res->mixer)) {
764                 dev_err(dev, "failed to get clock 'mixer'\n");
765                 return -ENODEV;
766         }
767
768         mixer_res->sclk_hdmi = devm_clk_get(dev, "sclk_hdmi");
769         if (IS_ERR(mixer_res->sclk_hdmi)) {
770                 dev_err(dev, "failed to get clock 'sclk_hdmi'\n");
771                 return -ENODEV;
772         }
773         res = platform_get_resource(mixer_ctx->pdev, IORESOURCE_MEM, 0);
774         if (res == NULL) {
775                 dev_err(dev, "get memory resource failed.\n");
776                 return -ENXIO;
777         }
778
779         mixer_res->mixer_regs = devm_ioremap(dev, res->start,
780                                                         resource_size(res));
781         if (mixer_res->mixer_regs == NULL) {
782                 dev_err(dev, "register mapping failed.\n");
783                 return -ENXIO;
784         }
785
786         res = platform_get_resource(mixer_ctx->pdev, IORESOURCE_IRQ, 0);
787         if (res == NULL) {
788                 dev_err(dev, "get interrupt resource failed.\n");
789                 return -ENXIO;
790         }
791
792         ret = devm_request_irq(dev, res->start, mixer_irq_handler,
793                                                 0, "drm_mixer", mixer_ctx);
794         if (ret) {
795                 dev_err(dev, "request interrupt failed.\n");
796                 return ret;
797         }
798         mixer_res->irq = res->start;
799
800         return 0;
801 }
802
803 static int vp_resources_init(struct mixer_context *mixer_ctx)
804 {
805         struct device *dev = &mixer_ctx->pdev->dev;
806         struct mixer_resources *mixer_res = &mixer_ctx->mixer_res;
807         struct resource *res;
808
809         mixer_res->vp = devm_clk_get(dev, "vp");
810         if (IS_ERR(mixer_res->vp)) {
811                 dev_err(dev, "failed to get clock 'vp'\n");
812                 return -ENODEV;
813         }
814
815         if (mixer_ctx->has_sclk) {
816                 mixer_res->sclk_mixer = devm_clk_get(dev, "sclk_mixer");
817                 if (IS_ERR(mixer_res->sclk_mixer)) {
818                         dev_err(dev, "failed to get clock 'sclk_mixer'\n");
819                         return -ENODEV;
820                 }
821                 mixer_res->mout_mixer = devm_clk_get(dev, "mout_mixer");
822                 if (IS_ERR(mixer_res->mout_mixer)) {
823                         dev_err(dev, "failed to get clock 'mout_mixer'\n");
824                         return -ENODEV;
825                 }
826
827                 if (mixer_res->sclk_hdmi && mixer_res->mout_mixer)
828                         clk_set_parent(mixer_res->mout_mixer,
829                                        mixer_res->sclk_hdmi);
830         }
831
832         res = platform_get_resource(mixer_ctx->pdev, IORESOURCE_MEM, 1);
833         if (res == NULL) {
834                 dev_err(dev, "get memory resource failed.\n");
835                 return -ENXIO;
836         }
837
838         mixer_res->vp_regs = devm_ioremap(dev, res->start,
839                                                         resource_size(res));
840         if (mixer_res->vp_regs == NULL) {
841                 dev_err(dev, "register mapping failed.\n");
842                 return -ENXIO;
843         }
844
845         return 0;
846 }
847
848 static int mixer_initialize(struct exynos_drm_manager *mgr,
849                         struct drm_device *drm_dev)
850 {
851         int ret;
852         struct mixer_context *mixer_ctx = mgr->ctx;
853         struct exynos_drm_private *priv;
854         priv = drm_dev->dev_private;
855
856         mgr->drm_dev = mixer_ctx->drm_dev = drm_dev;
857         mgr->pipe = mixer_ctx->pipe = priv->pipe++;
858
859         /* acquire resources: regs, irqs, clocks */
860         ret = mixer_resources_init(mixer_ctx);
861         if (ret) {
862                 DRM_ERROR("mixer_resources_init failed ret=%d\n", ret);
863                 return ret;
864         }
865
866         if (mixer_ctx->vp_enabled) {
867                 /* acquire vp resources: regs, irqs, clocks */
868                 ret = vp_resources_init(mixer_ctx);
869                 if (ret) {
870                         DRM_ERROR("vp_resources_init failed ret=%d\n", ret);
871                         return ret;
872                 }
873         }
874
875         if (!is_drm_iommu_supported(mixer_ctx->drm_dev))
876                 return 0;
877
878         return drm_iommu_attach_device(mixer_ctx->drm_dev, mixer_ctx->dev);
879 }
880
881 static void mixer_mgr_remove(struct exynos_drm_manager *mgr)
882 {
883         struct mixer_context *mixer_ctx = mgr->ctx;
884
885         if (is_drm_iommu_supported(mixer_ctx->drm_dev))
886                 drm_iommu_detach_device(mixer_ctx->drm_dev, mixer_ctx->dev);
887 }
888
889 static int mixer_enable_vblank(struct exynos_drm_manager *mgr)
890 {
891         struct mixer_context *mixer_ctx = mgr->ctx;
892         struct mixer_resources *res = &mixer_ctx->mixer_res;
893
894         if (!mixer_ctx->powered) {
895                 mixer_ctx->int_en |= MXR_INT_EN_VSYNC;
896                 return 0;
897         }
898
899         /* enable vsync interrupt */
900         mixer_reg_writemask(res, MXR_INT_EN, MXR_INT_EN_VSYNC,
901                         MXR_INT_EN_VSYNC);
902
903         return 0;
904 }
905
906 static void mixer_disable_vblank(struct exynos_drm_manager *mgr)
907 {
908         struct mixer_context *mixer_ctx = mgr->ctx;
909         struct mixer_resources *res = &mixer_ctx->mixer_res;
910
911         /* disable vsync interrupt */
912         mixer_reg_writemask(res, MXR_INT_EN, 0, MXR_INT_EN_VSYNC);
913 }
914
915 static void mixer_win_mode_set(struct exynos_drm_manager *mgr,
916                         struct exynos_drm_overlay *overlay)
917 {
918         struct mixer_context *mixer_ctx = mgr->ctx;
919         struct hdmi_win_data *win_data;
920         int win;
921
922         if (!overlay) {
923                 DRM_ERROR("overlay is NULL\n");
924                 return;
925         }
926
927         DRM_DEBUG_KMS("set [%d]x[%d] at (%d,%d) to [%d]x[%d] at (%d,%d)\n",
928                                  overlay->fb_width, overlay->fb_height,
929                                  overlay->fb_x, overlay->fb_y,
930                                  overlay->crtc_width, overlay->crtc_height,
931                                  overlay->crtc_x, overlay->crtc_y);
932
933         win = overlay->zpos;
934         if (win == DEFAULT_ZPOS)
935                 win = MIXER_DEFAULT_WIN;
936
937         if (win < 0 || win >= MIXER_WIN_NR) {
938                 DRM_ERROR("mixer window[%d] is wrong\n", win);
939                 return;
940         }
941
942         win_data = &mixer_ctx->win_data[win];
943
944         win_data->dma_addr = overlay->dma_addr[0];
945         win_data->chroma_dma_addr = overlay->dma_addr[1];
946         win_data->pixel_format = overlay->pixel_format;
947         win_data->bpp = overlay->bpp;
948
949         win_data->crtc_x = overlay->crtc_x;
950         win_data->crtc_y = overlay->crtc_y;
951         win_data->crtc_width = overlay->crtc_width;
952         win_data->crtc_height = overlay->crtc_height;
953
954         win_data->fb_x = overlay->fb_x;
955         win_data->fb_y = overlay->fb_y;
956         win_data->fb_width = overlay->fb_width;
957         win_data->fb_height = overlay->fb_height;
958         win_data->src_width = overlay->src_width;
959         win_data->src_height = overlay->src_height;
960
961         win_data->mode_width = overlay->mode_width;
962         win_data->mode_height = overlay->mode_height;
963
964         win_data->scan_flags = overlay->scan_flag;
965 }
966
967 static void mixer_win_commit(struct exynos_drm_manager *mgr, int zpos)
968 {
969         struct mixer_context *mixer_ctx = mgr->ctx;
970         int win = zpos == DEFAULT_ZPOS ? MIXER_DEFAULT_WIN : zpos;
971
972         DRM_DEBUG_KMS("win: %d\n", win);
973
974         mutex_lock(&mixer_ctx->mixer_mutex);
975         if (!mixer_ctx->powered) {
976                 mutex_unlock(&mixer_ctx->mixer_mutex);
977                 return;
978         }
979         mutex_unlock(&mixer_ctx->mixer_mutex);
980
981         if (win > 1 && mixer_ctx->vp_enabled)
982                 vp_video_buffer(mixer_ctx, win);
983         else
984                 mixer_graph_buffer(mixer_ctx, win);
985
986         mixer_ctx->win_data[win].enabled = true;
987 }
988
989 static void mixer_win_disable(struct exynos_drm_manager *mgr, int zpos)
990 {
991         struct mixer_context *mixer_ctx = mgr->ctx;
992         struct mixer_resources *res = &mixer_ctx->mixer_res;
993         int win = zpos == DEFAULT_ZPOS ? MIXER_DEFAULT_WIN : zpos;
994         unsigned long flags;
995
996         DRM_DEBUG_KMS("win: %d\n", win);
997
998         mutex_lock(&mixer_ctx->mixer_mutex);
999         if (!mixer_ctx->powered) {
1000                 mutex_unlock(&mixer_ctx->mixer_mutex);
1001                 mixer_ctx->win_data[win].resume = false;
1002                 return;
1003         }
1004         mutex_unlock(&mixer_ctx->mixer_mutex);
1005
1006         spin_lock_irqsave(&res->reg_slock, flags);
1007         mixer_vsync_set_update(mixer_ctx, false);
1008
1009         mixer_cfg_layer(mixer_ctx, win, false);
1010
1011         mixer_vsync_set_update(mixer_ctx, true);
1012         spin_unlock_irqrestore(&res->reg_slock, flags);
1013
1014         mixer_ctx->win_data[win].enabled = false;
1015 }
1016
1017 static void mixer_wait_for_vblank(struct exynos_drm_manager *mgr)
1018 {
1019         struct mixer_context *mixer_ctx = mgr->ctx;
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         drm_vblank_get(mgr->crtc->dev, mixer_ctx->pipe);
1029
1030         atomic_set(&mixer_ctx->wait_vsync_event, 1);
1031
1032         /*
1033          * wait for MIXER to signal VSYNC interrupt or return after
1034          * timeout which is set to 50ms (refresh rate of 20).
1035          */
1036         if (!wait_event_timeout(mixer_ctx->wait_vsync_queue,
1037                                 !atomic_read(&mixer_ctx->wait_vsync_event),
1038                                 HZ/20))
1039                 DRM_DEBUG_KMS("vblank wait timed out.\n");
1040
1041         drm_vblank_put(mgr->crtc->dev, mixer_ctx->pipe);
1042 }
1043
1044 static void mixer_window_suspend(struct exynos_drm_manager *mgr)
1045 {
1046         struct mixer_context *ctx = mgr->ctx;
1047         struct hdmi_win_data *win_data;
1048         int i;
1049
1050         for (i = 0; i < MIXER_WIN_NR; i++) {
1051                 win_data = &ctx->win_data[i];
1052                 win_data->resume = win_data->enabled;
1053                 mixer_win_disable(mgr, i);
1054         }
1055         mixer_wait_for_vblank(mgr);
1056 }
1057
1058 static void mixer_window_resume(struct exynos_drm_manager *mgr)
1059 {
1060         struct mixer_context *ctx = mgr->ctx;
1061         struct hdmi_win_data *win_data;
1062         int i;
1063
1064         for (i = 0; i < MIXER_WIN_NR; i++) {
1065                 win_data = &ctx->win_data[i];
1066                 win_data->enabled = win_data->resume;
1067                 win_data->resume = false;
1068                 if (win_data->enabled)
1069                         mixer_win_commit(mgr, i);
1070         }
1071 }
1072
1073 static void mixer_poweron(struct exynos_drm_manager *mgr)
1074 {
1075         struct mixer_context *ctx = mgr->ctx;
1076         struct mixer_resources *res = &ctx->mixer_res;
1077
1078         mutex_lock(&ctx->mixer_mutex);
1079         if (ctx->powered) {
1080                 mutex_unlock(&ctx->mixer_mutex);
1081                 return;
1082         }
1083
1084         mutex_unlock(&ctx->mixer_mutex);
1085
1086         pm_runtime_get_sync(ctx->dev);
1087
1088         clk_prepare_enable(res->mixer);
1089         if (ctx->vp_enabled) {
1090                 clk_prepare_enable(res->vp);
1091                 if (ctx->has_sclk)
1092                         clk_prepare_enable(res->sclk_mixer);
1093         }
1094
1095         mutex_lock(&ctx->mixer_mutex);
1096         ctx->powered = true;
1097         mutex_unlock(&ctx->mixer_mutex);
1098
1099         mixer_reg_writemask(res, MXR_STATUS, ~0, MXR_STATUS_SOFT_RESET);
1100
1101         mixer_reg_write(res, MXR_INT_EN, ctx->int_en);
1102         mixer_win_reset(ctx);
1103
1104         mixer_window_resume(mgr);
1105 }
1106
1107 static void mixer_poweroff(struct exynos_drm_manager *mgr)
1108 {
1109         struct mixer_context *ctx = mgr->ctx;
1110         struct mixer_resources *res = &ctx->mixer_res;
1111
1112         mutex_lock(&ctx->mixer_mutex);
1113         if (!ctx->powered) {
1114                 mutex_unlock(&ctx->mixer_mutex);
1115                 return;
1116         }
1117         mutex_unlock(&ctx->mixer_mutex);
1118
1119         mixer_stop(ctx);
1120         mixer_window_suspend(mgr);
1121
1122         ctx->int_en = mixer_reg_read(res, MXR_INT_EN);
1123
1124         mutex_lock(&ctx->mixer_mutex);
1125         ctx->powered = false;
1126         mutex_unlock(&ctx->mixer_mutex);
1127
1128         clk_disable_unprepare(res->mixer);
1129         if (ctx->vp_enabled) {
1130                 clk_disable_unprepare(res->vp);
1131                 if (ctx->has_sclk)
1132                         clk_disable_unprepare(res->sclk_mixer);
1133         }
1134
1135         pm_runtime_put_sync(ctx->dev);
1136 }
1137
1138 static void mixer_dpms(struct exynos_drm_manager *mgr, int mode)
1139 {
1140         switch (mode) {
1141         case DRM_MODE_DPMS_ON:
1142                 mixer_poweron(mgr);
1143                 break;
1144         case DRM_MODE_DPMS_STANDBY:
1145         case DRM_MODE_DPMS_SUSPEND:
1146         case DRM_MODE_DPMS_OFF:
1147                 mixer_poweroff(mgr);
1148                 break;
1149         default:
1150                 DRM_DEBUG_KMS("unknown dpms mode: %d\n", mode);
1151                 break;
1152         }
1153 }
1154
1155 /* Only valid for Mixer version 16.0.33.0 */
1156 int mixer_check_mode(struct drm_display_mode *mode)
1157 {
1158         u32 w, h;
1159
1160         w = mode->hdisplay;
1161         h = mode->vdisplay;
1162
1163         DRM_DEBUG_KMS("xres=%d, yres=%d, refresh=%d, intl=%d\n",
1164                 mode->hdisplay, mode->vdisplay, mode->vrefresh,
1165                 (mode->flags & DRM_MODE_FLAG_INTERLACE) ? 1 : 0);
1166
1167         if ((w >= 464 && w <= 720 && h >= 261 && h <= 576) ||
1168                 (w >= 1024 && w <= 1280 && h >= 576 && h <= 720) ||
1169                 (w >= 1664 && w <= 1920 && h >= 936 && h <= 1080))
1170                 return 0;
1171
1172         return -EINVAL;
1173 }
1174
1175 static struct exynos_drm_manager_ops mixer_manager_ops = {
1176         .dpms                   = mixer_dpms,
1177         .enable_vblank          = mixer_enable_vblank,
1178         .disable_vblank         = mixer_disable_vblank,
1179         .wait_for_vblank        = mixer_wait_for_vblank,
1180         .win_mode_set           = mixer_win_mode_set,
1181         .win_commit             = mixer_win_commit,
1182         .win_disable            = mixer_win_disable,
1183 };
1184
1185 static struct exynos_drm_manager mixer_manager = {
1186         .type                   = EXYNOS_DISPLAY_TYPE_HDMI,
1187         .ops                    = &mixer_manager_ops,
1188 };
1189
1190 static struct mixer_drv_data exynos5420_mxr_drv_data = {
1191         .version = MXR_VER_128_0_0_184,
1192         .is_vp_enabled = 0,
1193 };
1194
1195 static struct mixer_drv_data exynos5250_mxr_drv_data = {
1196         .version = MXR_VER_16_0_33_0,
1197         .is_vp_enabled = 0,
1198 };
1199
1200 static struct mixer_drv_data exynos4212_mxr_drv_data = {
1201         .version = MXR_VER_0_0_0_16,
1202         .is_vp_enabled = 1,
1203 };
1204
1205 static struct mixer_drv_data exynos4210_mxr_drv_data = {
1206         .version = MXR_VER_0_0_0_16,
1207         .is_vp_enabled = 1,
1208         .has_sclk = 1,
1209 };
1210
1211 static struct platform_device_id mixer_driver_types[] = {
1212         {
1213                 .name           = "s5p-mixer",
1214                 .driver_data    = (unsigned long)&exynos4210_mxr_drv_data,
1215         }, {
1216                 .name           = "exynos5-mixer",
1217                 .driver_data    = (unsigned long)&exynos5250_mxr_drv_data,
1218         }, {
1219                 /* end node */
1220         }
1221 };
1222
1223 static struct of_device_id mixer_match_types[] = {
1224         {
1225                 .compatible = "samsung,exynos4210-mixer",
1226                 .data   = &exynos4210_mxr_drv_data,
1227         }, {
1228                 .compatible = "samsung,exynos4212-mixer",
1229                 .data   = &exynos4212_mxr_drv_data,
1230         }, {
1231                 .compatible = "samsung,exynos5-mixer",
1232                 .data   = &exynos5250_mxr_drv_data,
1233         }, {
1234                 .compatible = "samsung,exynos5250-mixer",
1235                 .data   = &exynos5250_mxr_drv_data,
1236         }, {
1237                 .compatible = "samsung,exynos5420-mixer",
1238                 .data   = &exynos5420_mxr_drv_data,
1239         }, {
1240                 /* end node */
1241         }
1242 };
1243
1244 static int mixer_bind(struct device *dev, struct device *manager, void *data)
1245 {
1246         struct platform_device *pdev = to_platform_device(dev);
1247         struct drm_device *drm_dev = data;
1248         struct mixer_context *ctx;
1249         struct mixer_drv_data *drv;
1250         int ret;
1251
1252         dev_info(dev, "probe start\n");
1253
1254         ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
1255         if (!ctx) {
1256                 DRM_ERROR("failed to alloc mixer context.\n");
1257                 return -ENOMEM;
1258         }
1259
1260         mutex_init(&ctx->mixer_mutex);
1261
1262         if (dev->of_node) {
1263                 const struct of_device_id *match;
1264                 match = of_match_node(mixer_match_types, dev->of_node);
1265                 drv = (struct mixer_drv_data *)match->data;
1266         } else {
1267                 drv = (struct mixer_drv_data *)
1268                         platform_get_device_id(pdev)->driver_data;
1269         }
1270
1271         ctx->pdev = pdev;
1272         ctx->dev = dev;
1273         ctx->vp_enabled = drv->is_vp_enabled;
1274         ctx->has_sclk = drv->has_sclk;
1275         ctx->mxr_ver = drv->version;
1276         init_waitqueue_head(&ctx->wait_vsync_queue);
1277         atomic_set(&ctx->wait_vsync_event, 0);
1278
1279         mixer_manager.ctx = ctx;
1280         ret = mixer_initialize(&mixer_manager, drm_dev);
1281         if (ret)
1282                 return ret;
1283
1284         platform_set_drvdata(pdev, &mixer_manager);
1285         ret = exynos_drm_crtc_create(&mixer_manager);
1286         if (ret) {
1287                 mixer_mgr_remove(&mixer_manager);
1288                 return ret;
1289         }
1290
1291         pm_runtime_enable(dev);
1292
1293         return 0;
1294 }
1295
1296 static void mixer_unbind(struct device *dev, struct device *master, void *data)
1297 {
1298         struct exynos_drm_manager *mgr = dev_get_drvdata(dev);
1299         struct drm_crtc *crtc = mgr->crtc;
1300
1301         dev_info(dev, "remove successful\n");
1302
1303         mixer_mgr_remove(mgr);
1304
1305         pm_runtime_disable(dev);
1306
1307         crtc->funcs->destroy(crtc);
1308 }
1309
1310 static const struct component_ops mixer_component_ops = {
1311         .bind   = mixer_bind,
1312         .unbind = mixer_unbind,
1313 };
1314
1315 static int mixer_probe(struct platform_device *pdev)
1316 {
1317         int ret;
1318
1319         ret = exynos_drm_component_add(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC,
1320                                         mixer_manager.type);
1321         if (ret)
1322                 return ret;
1323
1324         ret = component_add(&pdev->dev, &mixer_component_ops);
1325         if (ret)
1326                 exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC);
1327
1328         return ret;
1329 }
1330
1331 static int mixer_remove(struct platform_device *pdev)
1332 {
1333         component_del(&pdev->dev, &mixer_component_ops);
1334         exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC);
1335
1336         return 0;
1337 }
1338
1339 struct platform_driver mixer_driver = {
1340         .driver = {
1341                 .name = "exynos-mixer",
1342                 .owner = THIS_MODULE,
1343                 .of_match_table = mixer_match_types,
1344         },
1345         .probe = mixer_probe,
1346         .remove = mixer_remove,
1347         .id_table       = mixer_driver_types,
1348 };