drm/exynos: stop mixer before gating clocks during poweroff
[cascardo/linux.git] / drivers / gpu / drm / exynos / exynos_mixer.c
1 /*
2  * Copyright (C) 2011 Samsung Electronics Co.Ltd
3  * Authors:
4  * Seung-Woo Kim <sw0312.kim@samsung.com>
5  *      Inki Dae <inki.dae@samsung.com>
6  *      Joonyoung Shim <jy0922.shim@samsung.com>
7  *
8  * Based on drivers/media/video/s5p-tv/mixer_reg.c
9  *
10  * This program is free software; you can redistribute  it and/or modify it
11  * under  the terms of  the GNU General  Public License as published by the
12  * Free Software Foundation;  either version 2 of the  License, or (at your
13  * option) any later version.
14  *
15  */
16
17 #include <drm/drmP.h>
18
19 #include "regs-mixer.h"
20 #include "regs-vp.h"
21
22 #include <linux/kernel.h>
23 #include <linux/spinlock.h>
24 #include <linux/wait.h>
25 #include <linux/i2c.h>
26 #include <linux/platform_device.h>
27 #include <linux/interrupt.h>
28 #include <linux/irq.h>
29 #include <linux/delay.h>
30 #include <linux/pm_runtime.h>
31 #include <linux/clk.h>
32 #include <linux/regulator/consumer.h>
33 #include <linux/of.h>
34 #include <linux/component.h>
35
36 #include <drm/exynos_drm.h>
37
38 #include "exynos_drm_drv.h"
39 #include "exynos_drm_crtc.h"
40 #include "exynos_drm_iommu.h"
41 #include "exynos_mixer.h"
42
43 #define get_mixer_manager(dev)  platform_get_drvdata(to_platform_device(dev))
44
45 #define MIXER_WIN_NR            3
46 #define MIXER_DEFAULT_WIN       0
47
48 struct hdmi_win_data {
49         dma_addr_t              dma_addr;
50         dma_addr_t              chroma_dma_addr;
51         uint32_t                pixel_format;
52         unsigned int            bpp;
53         unsigned int            crtc_x;
54         unsigned int            crtc_y;
55         unsigned int            crtc_width;
56         unsigned int            crtc_height;
57         unsigned int            fb_x;
58         unsigned int            fb_y;
59         unsigned int            fb_width;
60         unsigned int            fb_height;
61         unsigned int            src_width;
62         unsigned int            src_height;
63         unsigned int            mode_width;
64         unsigned int            mode_height;
65         unsigned int            scan_flags;
66         bool                    enabled;
67         bool                    resume;
68 };
69
70 struct mixer_resources {
71         int                     irq;
72         void __iomem            *mixer_regs;
73         void __iomem            *vp_regs;
74         spinlock_t              reg_slock;
75         struct clk              *mixer;
76         struct clk              *vp;
77         struct clk              *sclk_mixer;
78         struct clk              *sclk_hdmi;
79         struct clk              *sclk_dac;
80 };
81
82 enum mixer_version_id {
83         MXR_VER_0_0_0_16,
84         MXR_VER_16_0_33_0,
85         MXR_VER_128_0_0_184,
86 };
87
88 struct mixer_context {
89         struct platform_device *pdev;
90         struct device           *dev;
91         struct drm_device       *drm_dev;
92         int                     pipe;
93         bool                    interlace;
94         bool                    powered;
95         bool                    vp_enabled;
96         u32                     int_en;
97
98         struct mutex            mixer_mutex;
99         struct mixer_resources  mixer_res;
100         struct hdmi_win_data    win_data[MIXER_WIN_NR];
101         enum mixer_version_id   mxr_ver;
102         wait_queue_head_t       wait_vsync_queue;
103         atomic_t                wait_vsync_event;
104 };
105
106 struct mixer_drv_data {
107         enum mixer_version_id   version;
108         bool                                    is_vp_enabled;
109 };
110
111 static const u8 filter_y_horiz_tap8[] = {
112         0,      -1,     -1,     -1,     -1,     -1,     -1,     -1,
113         -1,     -1,     -1,     -1,     -1,     0,      0,      0,
114         0,      2,      4,      5,      6,      6,      6,      6,
115         6,      5,      5,      4,      3,      2,      1,      1,
116         0,      -6,     -12,    -16,    -18,    -20,    -21,    -20,
117         -20,    -18,    -16,    -13,    -10,    -8,     -5,     -2,
118         127,    126,    125,    121,    114,    107,    99,     89,
119         79,     68,     57,     46,     35,     25,     16,     8,
120 };
121
122 static const u8 filter_y_vert_tap4[] = {
123         0,      -3,     -6,     -8,     -8,     -8,     -8,     -7,
124         -6,     -5,     -4,     -3,     -2,     -1,     -1,     0,
125         127,    126,    124,    118,    111,    102,    92,     81,
126         70,     59,     48,     37,     27,     19,     11,     5,
127         0,      5,      11,     19,     27,     37,     48,     59,
128         70,     81,     92,     102,    111,    118,    124,    126,
129         0,      0,      -1,     -1,     -2,     -3,     -4,     -5,
130         -6,     -7,     -8,     -8,     -8,     -8,     -6,     -3,
131 };
132
133 static const u8 filter_cr_horiz_tap4[] = {
134         0,      -3,     -6,     -8,     -8,     -8,     -8,     -7,
135         -6,     -5,     -4,     -3,     -2,     -1,     -1,     0,
136         127,    126,    124,    118,    111,    102,    92,     81,
137         70,     59,     48,     37,     27,     19,     11,     5,
138 };
139
140 static inline u32 vp_reg_read(struct mixer_resources *res, u32 reg_id)
141 {
142         return readl(res->vp_regs + reg_id);
143 }
144
145 static inline void vp_reg_write(struct mixer_resources *res, u32 reg_id,
146                                  u32 val)
147 {
148         writel(val, res->vp_regs + reg_id);
149 }
150
151 static inline void vp_reg_writemask(struct mixer_resources *res, u32 reg_id,
152                                  u32 val, u32 mask)
153 {
154         u32 old = vp_reg_read(res, reg_id);
155
156         val = (val & mask) | (old & ~mask);
157         writel(val, res->vp_regs + reg_id);
158 }
159
160 static inline u32 mixer_reg_read(struct mixer_resources *res, u32 reg_id)
161 {
162         return readl(res->mixer_regs + reg_id);
163 }
164
165 static inline void mixer_reg_write(struct mixer_resources *res, u32 reg_id,
166                                  u32 val)
167 {
168         writel(val, res->mixer_regs + reg_id);
169 }
170
171 static inline void mixer_reg_writemask(struct mixer_resources *res,
172                                  u32 reg_id, u32 val, u32 mask)
173 {
174         u32 old = mixer_reg_read(res, reg_id);
175
176         val = (val & mask) | (old & ~mask);
177         writel(val, res->mixer_regs + reg_id);
178 }
179
180 static void mixer_regs_dump(struct mixer_context *ctx)
181 {
182 #define DUMPREG(reg_id) \
183 do { \
184         DRM_DEBUG_KMS(#reg_id " = %08x\n", \
185                 (u32)readl(ctx->mixer_res.mixer_regs + reg_id)); \
186 } while (0)
187
188         DUMPREG(MXR_STATUS);
189         DUMPREG(MXR_CFG);
190         DUMPREG(MXR_INT_EN);
191         DUMPREG(MXR_INT_STATUS);
192
193         DUMPREG(MXR_LAYER_CFG);
194         DUMPREG(MXR_VIDEO_CFG);
195
196         DUMPREG(MXR_GRAPHIC0_CFG);
197         DUMPREG(MXR_GRAPHIC0_BASE);
198         DUMPREG(MXR_GRAPHIC0_SPAN);
199         DUMPREG(MXR_GRAPHIC0_WH);
200         DUMPREG(MXR_GRAPHIC0_SXY);
201         DUMPREG(MXR_GRAPHIC0_DXY);
202
203         DUMPREG(MXR_GRAPHIC1_CFG);
204         DUMPREG(MXR_GRAPHIC1_BASE);
205         DUMPREG(MXR_GRAPHIC1_SPAN);
206         DUMPREG(MXR_GRAPHIC1_WH);
207         DUMPREG(MXR_GRAPHIC1_SXY);
208         DUMPREG(MXR_GRAPHIC1_DXY);
209 #undef DUMPREG
210 }
211
212 static void vp_regs_dump(struct mixer_context *ctx)
213 {
214 #define DUMPREG(reg_id) \
215 do { \
216         DRM_DEBUG_KMS(#reg_id " = %08x\n", \
217                 (u32) readl(ctx->mixer_res.vp_regs + reg_id)); \
218 } while (0)
219
220         DUMPREG(VP_ENABLE);
221         DUMPREG(VP_SRESET);
222         DUMPREG(VP_SHADOW_UPDATE);
223         DUMPREG(VP_FIELD_ID);
224         DUMPREG(VP_MODE);
225         DUMPREG(VP_IMG_SIZE_Y);
226         DUMPREG(VP_IMG_SIZE_C);
227         DUMPREG(VP_PER_RATE_CTRL);
228         DUMPREG(VP_TOP_Y_PTR);
229         DUMPREG(VP_BOT_Y_PTR);
230         DUMPREG(VP_TOP_C_PTR);
231         DUMPREG(VP_BOT_C_PTR);
232         DUMPREG(VP_ENDIAN_MODE);
233         DUMPREG(VP_SRC_H_POSITION);
234         DUMPREG(VP_SRC_V_POSITION);
235         DUMPREG(VP_SRC_WIDTH);
236         DUMPREG(VP_SRC_HEIGHT);
237         DUMPREG(VP_DST_H_POSITION);
238         DUMPREG(VP_DST_V_POSITION);
239         DUMPREG(VP_DST_WIDTH);
240         DUMPREG(VP_DST_HEIGHT);
241         DUMPREG(VP_H_RATIO);
242         DUMPREG(VP_V_RATIO);
243
244 #undef DUMPREG
245 }
246
247 static inline void vp_filter_set(struct mixer_resources *res,
248                 int reg_id, const u8 *data, unsigned int size)
249 {
250         /* assure 4-byte align */
251         BUG_ON(size & 3);
252         for (; size; size -= 4, reg_id += 4, data += 4) {
253                 u32 val = (data[0] << 24) |  (data[1] << 16) |
254                         (data[2] << 8) | data[3];
255                 vp_reg_write(res, reg_id, val);
256         }
257 }
258
259 static void vp_default_filter(struct mixer_resources *res)
260 {
261         vp_filter_set(res, VP_POLY8_Y0_LL,
262                 filter_y_horiz_tap8, sizeof(filter_y_horiz_tap8));
263         vp_filter_set(res, VP_POLY4_Y0_LL,
264                 filter_y_vert_tap4, sizeof(filter_y_vert_tap4));
265         vp_filter_set(res, VP_POLY4_C0_LL,
266                 filter_cr_horiz_tap4, sizeof(filter_cr_horiz_tap4));
267 }
268
269 static void mixer_vsync_set_update(struct mixer_context *ctx, bool enable)
270 {
271         struct mixer_resources *res = &ctx->mixer_res;
272
273         /* block update on vsync */
274         mixer_reg_writemask(res, MXR_STATUS, enable ?
275                         MXR_STATUS_SYNC_ENABLE : 0, MXR_STATUS_SYNC_ENABLE);
276
277         if (ctx->vp_enabled)
278                 vp_reg_write(res, VP_SHADOW_UPDATE, enable ?
279                         VP_SHADOW_UPDATE_ENABLE : 0);
280 }
281
282 static void mixer_cfg_scan(struct mixer_context *ctx, unsigned int height)
283 {
284         struct mixer_resources *res = &ctx->mixer_res;
285         u32 val;
286
287         /* choosing between interlace and progressive mode */
288         val = (ctx->interlace ? MXR_CFG_SCAN_INTERLACE :
289                                 MXR_CFG_SCAN_PROGRASSIVE);
290
291         if (ctx->mxr_ver != MXR_VER_128_0_0_184) {
292                 /* choosing between proper HD and SD mode */
293                 if (height <= 480)
294                         val |= MXR_CFG_SCAN_NTSC | MXR_CFG_SCAN_SD;
295                 else if (height <= 576)
296                         val |= MXR_CFG_SCAN_PAL | MXR_CFG_SCAN_SD;
297                 else if (height <= 720)
298                         val |= MXR_CFG_SCAN_HD_720 | MXR_CFG_SCAN_HD;
299                 else if (height <= 1080)
300                         val |= MXR_CFG_SCAN_HD_1080 | MXR_CFG_SCAN_HD;
301                 else
302                         val |= MXR_CFG_SCAN_HD_720 | MXR_CFG_SCAN_HD;
303         }
304
305         mixer_reg_writemask(res, MXR_CFG, val, MXR_CFG_SCAN_MASK);
306 }
307
308 static void mixer_cfg_rgb_fmt(struct mixer_context *ctx, unsigned int height)
309 {
310         struct mixer_resources *res = &ctx->mixer_res;
311         u32 val;
312
313         if (height == 480) {
314                 val = MXR_CFG_RGB601_0_255;
315         } else if (height == 576) {
316                 val = MXR_CFG_RGB601_0_255;
317         } else if (height == 720) {
318                 val = MXR_CFG_RGB709_16_235;
319                 mixer_reg_write(res, MXR_CM_COEFF_Y,
320                                 (1 << 30) | (94 << 20) | (314 << 10) |
321                                 (32 << 0));
322                 mixer_reg_write(res, MXR_CM_COEFF_CB,
323                                 (972 << 20) | (851 << 10) | (225 << 0));
324                 mixer_reg_write(res, MXR_CM_COEFF_CR,
325                                 (225 << 20) | (820 << 10) | (1004 << 0));
326         } else if (height == 1080) {
327                 val = MXR_CFG_RGB709_16_235;
328                 mixer_reg_write(res, MXR_CM_COEFF_Y,
329                                 (1 << 30) | (94 << 20) | (314 << 10) |
330                                 (32 << 0));
331                 mixer_reg_write(res, MXR_CM_COEFF_CB,
332                                 (972 << 20) | (851 << 10) | (225 << 0));
333                 mixer_reg_write(res, MXR_CM_COEFF_CR,
334                                 (225 << 20) | (820 << 10) | (1004 << 0));
335         } else {
336                 val = MXR_CFG_RGB709_16_235;
337                 mixer_reg_write(res, MXR_CM_COEFF_Y,
338                                 (1 << 30) | (94 << 20) | (314 << 10) |
339                                 (32 << 0));
340                 mixer_reg_write(res, MXR_CM_COEFF_CB,
341                                 (972 << 20) | (851 << 10) | (225 << 0));
342                 mixer_reg_write(res, MXR_CM_COEFF_CR,
343                                 (225 << 20) | (820 << 10) | (1004 << 0));
344         }
345
346         mixer_reg_writemask(res, MXR_CFG, val, MXR_CFG_RGB_FMT_MASK);
347 }
348
349 static void mixer_cfg_layer(struct mixer_context *ctx, int win, bool enable)
350 {
351         struct mixer_resources *res = &ctx->mixer_res;
352         u32 val = enable ? ~0 : 0;
353
354         switch (win) {
355         case 0:
356                 mixer_reg_writemask(res, MXR_CFG, val, MXR_CFG_GRP0_ENABLE);
357                 break;
358         case 1:
359                 mixer_reg_writemask(res, MXR_CFG, val, MXR_CFG_GRP1_ENABLE);
360                 break;
361         case 2:
362                 if (ctx->vp_enabled) {
363                         vp_reg_writemask(res, VP_ENABLE, val, VP_ENABLE_ON);
364                         mixer_reg_writemask(res, MXR_CFG, val,
365                                 MXR_CFG_VP_ENABLE);
366                 }
367                 break;
368         }
369 }
370
371 static void mixer_run(struct mixer_context *ctx)
372 {
373         struct mixer_resources *res = &ctx->mixer_res;
374
375         mixer_reg_writemask(res, MXR_STATUS, ~0, MXR_STATUS_REG_RUN);
376
377         mixer_regs_dump(ctx);
378 }
379
380 static void mixer_stop(struct mixer_context *ctx)
381 {
382         struct mixer_resources *res = &ctx->mixer_res;
383         int timeout = 20;
384
385         mixer_reg_writemask(res, MXR_STATUS, 0, MXR_STATUS_REG_RUN);
386
387         while (!(mixer_reg_read(res, MXR_STATUS) & MXR_STATUS_REG_IDLE) &&
388                         --timeout)
389                 usleep_range(10000, 12000);
390
391         mixer_regs_dump(ctx);
392 }
393
394 static void vp_video_buffer(struct mixer_context *ctx, int win)
395 {
396         struct mixer_resources *res = &ctx->mixer_res;
397         unsigned long flags;
398         struct hdmi_win_data *win_data;
399         unsigned int x_ratio, y_ratio;
400         unsigned int buf_num = 1;
401         dma_addr_t luma_addr[2], chroma_addr[2];
402         bool tiled_mode = false;
403         bool crcb_mode = false;
404         u32 val;
405
406         win_data = &ctx->win_data[win];
407
408         switch (win_data->pixel_format) {
409         case DRM_FORMAT_NV12MT:
410                 tiled_mode = true;
411         case DRM_FORMAT_NV12:
412                 crcb_mode = false;
413                 buf_num = 2;
414                 break;
415         /* TODO: single buffer format NV12, NV21 */
416         default:
417                 /* ignore pixel format at disable time */
418                 if (!win_data->dma_addr)
419                         break;
420
421                 DRM_ERROR("pixel format for vp is wrong [%d].\n",
422                                 win_data->pixel_format);
423                 return;
424         }
425
426         /* scaling feature: (src << 16) / dst */
427         x_ratio = (win_data->src_width << 16) / win_data->crtc_width;
428         y_ratio = (win_data->src_height << 16) / win_data->crtc_height;
429
430         if (buf_num == 2) {
431                 luma_addr[0] = win_data->dma_addr;
432                 chroma_addr[0] = win_data->chroma_dma_addr;
433         } else {
434                 luma_addr[0] = win_data->dma_addr;
435                 chroma_addr[0] = win_data->dma_addr
436                         + (win_data->fb_width * win_data->fb_height);
437         }
438
439         if (win_data->scan_flags & DRM_MODE_FLAG_INTERLACE) {
440                 ctx->interlace = true;
441                 if (tiled_mode) {
442                         luma_addr[1] = luma_addr[0] + 0x40;
443                         chroma_addr[1] = chroma_addr[0] + 0x40;
444                 } else {
445                         luma_addr[1] = luma_addr[0] + win_data->fb_width;
446                         chroma_addr[1] = chroma_addr[0] + win_data->fb_width;
447                 }
448         } else {
449                 ctx->interlace = false;
450                 luma_addr[1] = 0;
451                 chroma_addr[1] = 0;
452         }
453
454         spin_lock_irqsave(&res->reg_slock, flags);
455         mixer_vsync_set_update(ctx, false);
456
457         /* interlace or progressive scan mode */
458         val = (ctx->interlace ? ~0 : 0);
459         vp_reg_writemask(res, VP_MODE, val, VP_MODE_LINE_SKIP);
460
461         /* setup format */
462         val = (crcb_mode ? VP_MODE_NV21 : VP_MODE_NV12);
463         val |= (tiled_mode ? VP_MODE_MEM_TILED : VP_MODE_MEM_LINEAR);
464         vp_reg_writemask(res, VP_MODE, val, VP_MODE_FMT_MASK);
465
466         /* setting size of input image */
467         vp_reg_write(res, VP_IMG_SIZE_Y, VP_IMG_HSIZE(win_data->fb_width) |
468                 VP_IMG_VSIZE(win_data->fb_height));
469         /* chroma height has to reduced by 2 to avoid chroma distorions */
470         vp_reg_write(res, VP_IMG_SIZE_C, VP_IMG_HSIZE(win_data->fb_width) |
471                 VP_IMG_VSIZE(win_data->fb_height / 2));
472
473         vp_reg_write(res, VP_SRC_WIDTH, win_data->src_width);
474         vp_reg_write(res, VP_SRC_HEIGHT, win_data->src_height);
475         vp_reg_write(res, VP_SRC_H_POSITION,
476                         VP_SRC_H_POSITION_VAL(win_data->fb_x));
477         vp_reg_write(res, VP_SRC_V_POSITION, win_data->fb_y);
478
479         vp_reg_write(res, VP_DST_WIDTH, win_data->crtc_width);
480         vp_reg_write(res, VP_DST_H_POSITION, win_data->crtc_x);
481         if (ctx->interlace) {
482                 vp_reg_write(res, VP_DST_HEIGHT, win_data->crtc_height / 2);
483                 vp_reg_write(res, VP_DST_V_POSITION, win_data->crtc_y / 2);
484         } else {
485                 vp_reg_write(res, VP_DST_HEIGHT, win_data->crtc_height);
486                 vp_reg_write(res, VP_DST_V_POSITION, win_data->crtc_y);
487         }
488
489         vp_reg_write(res, VP_H_RATIO, x_ratio);
490         vp_reg_write(res, VP_V_RATIO, y_ratio);
491
492         vp_reg_write(res, VP_ENDIAN_MODE, VP_ENDIAN_MODE_LITTLE);
493
494         /* set buffer address to vp */
495         vp_reg_write(res, VP_TOP_Y_PTR, luma_addr[0]);
496         vp_reg_write(res, VP_BOT_Y_PTR, luma_addr[1]);
497         vp_reg_write(res, VP_TOP_C_PTR, chroma_addr[0]);
498         vp_reg_write(res, VP_BOT_C_PTR, chroma_addr[1]);
499
500         mixer_cfg_scan(ctx, win_data->mode_height);
501         mixer_cfg_rgb_fmt(ctx, win_data->mode_height);
502         mixer_cfg_layer(ctx, win, true);
503         mixer_run(ctx);
504
505         mixer_vsync_set_update(ctx, true);
506         spin_unlock_irqrestore(&res->reg_slock, flags);
507
508         vp_regs_dump(ctx);
509 }
510
511 static void mixer_layer_update(struct mixer_context *ctx)
512 {
513         struct mixer_resources *res = &ctx->mixer_res;
514         u32 val;
515
516         val = mixer_reg_read(res, MXR_CFG);
517
518         /* allow one update per vsync only */
519         if (!(val & MXR_CFG_LAYER_UPDATE_COUNT_MASK))
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->fb_height);
585                 val |= MXR_MXR_RES_WIDTH(win_data->fb_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->sclk_hdmi = devm_clk_get(dev, "sclk_hdmi");
772         if (IS_ERR(mixer_res->sclk_hdmi)) {
773                 dev_err(dev, "failed to get clock 'sclk_hdmi'\n");
774                 return -ENODEV;
775         }
776         res = platform_get_resource(mixer_ctx->pdev, IORESOURCE_MEM, 0);
777         if (res == NULL) {
778                 dev_err(dev, "get memory resource failed.\n");
779                 return -ENXIO;
780         }
781
782         mixer_res->mixer_regs = devm_ioremap(dev, res->start,
783                                                         resource_size(res));
784         if (mixer_res->mixer_regs == NULL) {
785                 dev_err(dev, "register mapping failed.\n");
786                 return -ENXIO;
787         }
788
789         res = platform_get_resource(mixer_ctx->pdev, IORESOURCE_IRQ, 0);
790         if (res == NULL) {
791                 dev_err(dev, "get interrupt resource failed.\n");
792                 return -ENXIO;
793         }
794
795         ret = devm_request_irq(dev, res->start, mixer_irq_handler,
796                                                 0, "drm_mixer", mixer_ctx);
797         if (ret) {
798                 dev_err(dev, "request interrupt failed.\n");
799                 return ret;
800         }
801         mixer_res->irq = res->start;
802
803         return 0;
804 }
805
806 static int vp_resources_init(struct mixer_context *mixer_ctx)
807 {
808         struct device *dev = &mixer_ctx->pdev->dev;
809         struct mixer_resources *mixer_res = &mixer_ctx->mixer_res;
810         struct resource *res;
811
812         mixer_res->vp = devm_clk_get(dev, "vp");
813         if (IS_ERR(mixer_res->vp)) {
814                 dev_err(dev, "failed to get clock 'vp'\n");
815                 return -ENODEV;
816         }
817         mixer_res->sclk_mixer = devm_clk_get(dev, "sclk_mixer");
818         if (IS_ERR(mixer_res->sclk_mixer)) {
819                 dev_err(dev, "failed to get clock 'sclk_mixer'\n");
820                 return -ENODEV;
821         }
822         mixer_res->sclk_dac = devm_clk_get(dev, "sclk_dac");
823         if (IS_ERR(mixer_res->sclk_dac)) {
824                 dev_err(dev, "failed to get clock 'sclk_dac'\n");
825                 return -ENODEV;
826         }
827
828         if (mixer_res->sclk_hdmi)
829                 clk_set_parent(mixer_res->sclk_mixer, mixer_res->sclk_hdmi);
830
831         res = platform_get_resource(mixer_ctx->pdev, IORESOURCE_MEM, 1);
832         if (res == NULL) {
833                 dev_err(dev, "get memory resource failed.\n");
834                 return -ENXIO;
835         }
836
837         mixer_res->vp_regs = devm_ioremap(dev, res->start,
838                                                         resource_size(res));
839         if (mixer_res->vp_regs == NULL) {
840                 dev_err(dev, "register mapping failed.\n");
841                 return -ENXIO;
842         }
843
844         return 0;
845 }
846
847 static int mixer_initialize(struct exynos_drm_manager *mgr,
848                         struct drm_device *drm_dev)
849 {
850         int ret;
851         struct mixer_context *mixer_ctx = mgr->ctx;
852         struct exynos_drm_private *priv;
853         priv = drm_dev->dev_private;
854
855         mgr->drm_dev = mixer_ctx->drm_dev = drm_dev;
856         mgr->pipe = mixer_ctx->pipe = priv->pipe++;
857
858         /* acquire resources: regs, irqs, clocks */
859         ret = mixer_resources_init(mixer_ctx);
860         if (ret) {
861                 DRM_ERROR("mixer_resources_init failed ret=%d\n", ret);
862                 return ret;
863         }
864
865         if (mixer_ctx->vp_enabled) {
866                 /* acquire vp resources: regs, irqs, clocks */
867                 ret = vp_resources_init(mixer_ctx);
868                 if (ret) {
869                         DRM_ERROR("vp_resources_init failed ret=%d\n", ret);
870                         return ret;
871                 }
872         }
873
874         if (!is_drm_iommu_supported(mixer_ctx->drm_dev))
875                 return 0;
876
877         return drm_iommu_attach_device(mixer_ctx->drm_dev, mixer_ctx->dev);
878 }
879
880 static void mixer_mgr_remove(struct exynos_drm_manager *mgr)
881 {
882         struct mixer_context *mixer_ctx = mgr->ctx;
883
884         if (is_drm_iommu_supported(mixer_ctx->drm_dev))
885                 drm_iommu_detach_device(mixer_ctx->drm_dev, mixer_ctx->dev);
886 }
887
888 static int mixer_enable_vblank(struct exynos_drm_manager *mgr)
889 {
890         struct mixer_context *mixer_ctx = mgr->ctx;
891         struct mixer_resources *res = &mixer_ctx->mixer_res;
892
893         if (!mixer_ctx->powered) {
894                 mixer_ctx->int_en |= MXR_INT_EN_VSYNC;
895                 return 0;
896         }
897
898         /* enable vsync interrupt */
899         mixer_reg_writemask(res, MXR_INT_EN, MXR_INT_EN_VSYNC,
900                         MXR_INT_EN_VSYNC);
901
902         return 0;
903 }
904
905 static void mixer_disable_vblank(struct exynos_drm_manager *mgr)
906 {
907         struct mixer_context *mixer_ctx = mgr->ctx;
908         struct mixer_resources *res = &mixer_ctx->mixer_res;
909
910         /* disable vsync interrupt */
911         mixer_reg_writemask(res, MXR_INT_EN, 0, MXR_INT_EN_VSYNC);
912 }
913
914 static void mixer_win_mode_set(struct exynos_drm_manager *mgr,
915                         struct exynos_drm_overlay *overlay)
916 {
917         struct mixer_context *mixer_ctx = mgr->ctx;
918         struct hdmi_win_data *win_data;
919         int win;
920
921         if (!overlay) {
922                 DRM_ERROR("overlay is NULL\n");
923                 return;
924         }
925
926         DRM_DEBUG_KMS("set [%d]x[%d] at (%d,%d) to [%d]x[%d] at (%d,%d)\n",
927                                  overlay->fb_width, overlay->fb_height,
928                                  overlay->fb_x, overlay->fb_y,
929                                  overlay->crtc_width, overlay->crtc_height,
930                                  overlay->crtc_x, overlay->crtc_y);
931
932         win = overlay->zpos;
933         if (win == DEFAULT_ZPOS)
934                 win = MIXER_DEFAULT_WIN;
935
936         if (win < 0 || win >= MIXER_WIN_NR) {
937                 DRM_ERROR("mixer window[%d] is wrong\n", win);
938                 return;
939         }
940
941         win_data = &mixer_ctx->win_data[win];
942
943         win_data->dma_addr = overlay->dma_addr[0];
944         win_data->chroma_dma_addr = overlay->dma_addr[1];
945         win_data->pixel_format = overlay->pixel_format;
946         win_data->bpp = overlay->bpp;
947
948         win_data->crtc_x = overlay->crtc_x;
949         win_data->crtc_y = overlay->crtc_y;
950         win_data->crtc_width = overlay->crtc_width;
951         win_data->crtc_height = overlay->crtc_height;
952
953         win_data->fb_x = overlay->fb_x;
954         win_data->fb_y = overlay->fb_y;
955         win_data->fb_width = overlay->fb_width;
956         win_data->fb_height = overlay->fb_height;
957         win_data->src_width = overlay->src_width;
958         win_data->src_height = overlay->src_height;
959
960         win_data->mode_width = overlay->mode_width;
961         win_data->mode_height = overlay->mode_height;
962
963         win_data->scan_flags = overlay->scan_flag;
964 }
965
966 static void mixer_win_commit(struct exynos_drm_manager *mgr, int zpos)
967 {
968         struct mixer_context *mixer_ctx = mgr->ctx;
969         int win = zpos == DEFAULT_ZPOS ? MIXER_DEFAULT_WIN : zpos;
970
971         DRM_DEBUG_KMS("win: %d\n", win);
972
973         mutex_lock(&mixer_ctx->mixer_mutex);
974         if (!mixer_ctx->powered) {
975                 mutex_unlock(&mixer_ctx->mixer_mutex);
976                 return;
977         }
978         mutex_unlock(&mixer_ctx->mixer_mutex);
979
980         if (win > 1 && mixer_ctx->vp_enabled)
981                 vp_video_buffer(mixer_ctx, win);
982         else
983                 mixer_graph_buffer(mixer_ctx, win);
984
985         mixer_ctx->win_data[win].enabled = true;
986 }
987
988 static void mixer_win_disable(struct exynos_drm_manager *mgr, int zpos)
989 {
990         struct mixer_context *mixer_ctx = mgr->ctx;
991         struct mixer_resources *res = &mixer_ctx->mixer_res;
992         int win = zpos == DEFAULT_ZPOS ? MIXER_DEFAULT_WIN : zpos;
993         unsigned long flags;
994
995         DRM_DEBUG_KMS("win: %d\n", win);
996
997         mutex_lock(&mixer_ctx->mixer_mutex);
998         if (!mixer_ctx->powered) {
999                 mutex_unlock(&mixer_ctx->mixer_mutex);
1000                 mixer_ctx->win_data[win].resume = false;
1001                 return;
1002         }
1003         mutex_unlock(&mixer_ctx->mixer_mutex);
1004
1005         spin_lock_irqsave(&res->reg_slock, flags);
1006         mixer_vsync_set_update(mixer_ctx, false);
1007
1008         mixer_cfg_layer(mixer_ctx, win, false);
1009
1010         mixer_vsync_set_update(mixer_ctx, true);
1011         spin_unlock_irqrestore(&res->reg_slock, flags);
1012
1013         mixer_ctx->win_data[win].enabled = false;
1014 }
1015
1016 static void mixer_wait_for_vblank(struct exynos_drm_manager *mgr)
1017 {
1018         struct mixer_context *mixer_ctx = mgr->ctx;
1019
1020         mutex_lock(&mixer_ctx->mixer_mutex);
1021         if (!mixer_ctx->powered) {
1022                 mutex_unlock(&mixer_ctx->mixer_mutex);
1023                 return;
1024         }
1025         mutex_unlock(&mixer_ctx->mixer_mutex);
1026
1027         atomic_set(&mixer_ctx->wait_vsync_event, 1);
1028
1029         /*
1030          * wait for MIXER to signal VSYNC interrupt or return after
1031          * timeout which is set to 50ms (refresh rate of 20).
1032          */
1033         if (!wait_event_timeout(mixer_ctx->wait_vsync_queue,
1034                                 !atomic_read(&mixer_ctx->wait_vsync_event),
1035                                 HZ/20))
1036                 DRM_DEBUG_KMS("vblank wait timed out.\n");
1037 }
1038
1039 static void mixer_window_suspend(struct exynos_drm_manager *mgr)
1040 {
1041         struct mixer_context *ctx = mgr->ctx;
1042         struct hdmi_win_data *win_data;
1043         int i;
1044
1045         for (i = 0; i < MIXER_WIN_NR; i++) {
1046                 win_data = &ctx->win_data[i];
1047                 win_data->resume = win_data->enabled;
1048                 mixer_win_disable(mgr, i);
1049         }
1050         mixer_wait_for_vblank(mgr);
1051 }
1052
1053 static void mixer_window_resume(struct exynos_drm_manager *mgr)
1054 {
1055         struct mixer_context *ctx = mgr->ctx;
1056         struct hdmi_win_data *win_data;
1057         int i;
1058
1059         for (i = 0; i < MIXER_WIN_NR; i++) {
1060                 win_data = &ctx->win_data[i];
1061                 win_data->enabled = win_data->resume;
1062                 win_data->resume = false;
1063                 if (win_data->enabled)
1064                         mixer_win_commit(mgr, i);
1065         }
1066 }
1067
1068 static void mixer_poweron(struct exynos_drm_manager *mgr)
1069 {
1070         struct mixer_context *ctx = mgr->ctx;
1071         struct mixer_resources *res = &ctx->mixer_res;
1072
1073         mutex_lock(&ctx->mixer_mutex);
1074         if (ctx->powered) {
1075                 mutex_unlock(&ctx->mixer_mutex);
1076                 return;
1077         }
1078
1079         mutex_unlock(&ctx->mixer_mutex);
1080
1081         pm_runtime_get_sync(ctx->dev);
1082
1083         clk_prepare_enable(res->mixer);
1084         if (ctx->vp_enabled) {
1085                 clk_prepare_enable(res->vp);
1086                 clk_prepare_enable(res->sclk_mixer);
1087         }
1088
1089         mutex_lock(&ctx->mixer_mutex);
1090         ctx->powered = true;
1091         mutex_unlock(&ctx->mixer_mutex);
1092
1093         mixer_reg_write(res, MXR_INT_EN, ctx->int_en);
1094         mixer_win_reset(ctx);
1095
1096         mixer_window_resume(mgr);
1097 }
1098
1099 static void mixer_poweroff(struct exynos_drm_manager *mgr)
1100 {
1101         struct mixer_context *ctx = mgr->ctx;
1102         struct mixer_resources *res = &ctx->mixer_res;
1103
1104         mutex_lock(&ctx->mixer_mutex);
1105         if (!ctx->powered) {
1106                 mutex_unlock(&ctx->mixer_mutex);
1107                 return;
1108         }
1109         mutex_unlock(&ctx->mixer_mutex);
1110
1111         mixer_stop(ctx);
1112         mixer_window_suspend(mgr);
1113
1114         ctx->int_en = mixer_reg_read(res, MXR_INT_EN);
1115
1116         mutex_lock(&ctx->mixer_mutex);
1117         ctx->powered = false;
1118         mutex_unlock(&ctx->mixer_mutex);
1119
1120         clk_disable_unprepare(res->mixer);
1121         if (ctx->vp_enabled) {
1122                 clk_disable_unprepare(res->vp);
1123                 clk_disable_unprepare(res->sclk_mixer);
1124         }
1125
1126         pm_runtime_put_sync(ctx->dev);
1127 }
1128
1129 static void mixer_dpms(struct exynos_drm_manager *mgr, int mode)
1130 {
1131         switch (mode) {
1132         case DRM_MODE_DPMS_ON:
1133                 mixer_poweron(mgr);
1134                 break;
1135         case DRM_MODE_DPMS_STANDBY:
1136         case DRM_MODE_DPMS_SUSPEND:
1137         case DRM_MODE_DPMS_OFF:
1138                 mixer_poweroff(mgr);
1139                 break;
1140         default:
1141                 DRM_DEBUG_KMS("unknown dpms mode: %d\n", mode);
1142                 break;
1143         }
1144 }
1145
1146 /* Only valid for Mixer version 16.0.33.0 */
1147 int mixer_check_mode(struct drm_display_mode *mode)
1148 {
1149         u32 w, h;
1150
1151         w = mode->hdisplay;
1152         h = mode->vdisplay;
1153
1154         DRM_DEBUG_KMS("xres=%d, yres=%d, refresh=%d, intl=%d\n",
1155                 mode->hdisplay, mode->vdisplay, mode->vrefresh,
1156                 (mode->flags & DRM_MODE_FLAG_INTERLACE) ? 1 : 0);
1157
1158         if ((w >= 464 && w <= 720 && h >= 261 && h <= 576) ||
1159                 (w >= 1024 && w <= 1280 && h >= 576 && h <= 720) ||
1160                 (w >= 1664 && w <= 1920 && h >= 936 && h <= 1080))
1161                 return 0;
1162
1163         return -EINVAL;
1164 }
1165
1166 static struct exynos_drm_manager_ops mixer_manager_ops = {
1167         .dpms                   = mixer_dpms,
1168         .enable_vblank          = mixer_enable_vblank,
1169         .disable_vblank         = mixer_disable_vblank,
1170         .wait_for_vblank        = mixer_wait_for_vblank,
1171         .win_mode_set           = mixer_win_mode_set,
1172         .win_commit             = mixer_win_commit,
1173         .win_disable            = mixer_win_disable,
1174 };
1175
1176 static struct exynos_drm_manager mixer_manager = {
1177         .type                   = EXYNOS_DISPLAY_TYPE_HDMI,
1178         .ops                    = &mixer_manager_ops,
1179 };
1180
1181 static struct mixer_drv_data exynos5420_mxr_drv_data = {
1182         .version = MXR_VER_128_0_0_184,
1183         .is_vp_enabled = 0,
1184 };
1185
1186 static struct mixer_drv_data exynos5250_mxr_drv_data = {
1187         .version = MXR_VER_16_0_33_0,
1188         .is_vp_enabled = 0,
1189 };
1190
1191 static struct mixer_drv_data exynos4210_mxr_drv_data = {
1192         .version = MXR_VER_0_0_0_16,
1193         .is_vp_enabled = 1,
1194 };
1195
1196 static struct platform_device_id mixer_driver_types[] = {
1197         {
1198                 .name           = "s5p-mixer",
1199                 .driver_data    = (unsigned long)&exynos4210_mxr_drv_data,
1200         }, {
1201                 .name           = "exynos5-mixer",
1202                 .driver_data    = (unsigned long)&exynos5250_mxr_drv_data,
1203         }, {
1204                 /* end node */
1205         }
1206 };
1207
1208 static struct of_device_id mixer_match_types[] = {
1209         {
1210                 .compatible = "samsung,exynos5-mixer",
1211                 .data   = &exynos5250_mxr_drv_data,
1212         }, {
1213                 .compatible = "samsung,exynos5250-mixer",
1214                 .data   = &exynos5250_mxr_drv_data,
1215         }, {
1216                 .compatible = "samsung,exynos5420-mixer",
1217                 .data   = &exynos5420_mxr_drv_data,
1218         }, {
1219                 /* end node */
1220         }
1221 };
1222
1223 static int mixer_bind(struct device *dev, struct device *manager, void *data)
1224 {
1225         struct platform_device *pdev = to_platform_device(dev);
1226         struct drm_device *drm_dev = data;
1227         struct mixer_context *ctx;
1228         struct mixer_drv_data *drv;
1229         int ret;
1230
1231         dev_info(dev, "probe start\n");
1232
1233         ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
1234         if (!ctx) {
1235                 DRM_ERROR("failed to alloc mixer context.\n");
1236                 return -ENOMEM;
1237         }
1238
1239         mutex_init(&ctx->mixer_mutex);
1240
1241         if (dev->of_node) {
1242                 const struct of_device_id *match;
1243                 match = of_match_node(mixer_match_types, dev->of_node);
1244                 drv = (struct mixer_drv_data *)match->data;
1245         } else {
1246                 drv = (struct mixer_drv_data *)
1247                         platform_get_device_id(pdev)->driver_data;
1248         }
1249
1250         ctx->pdev = pdev;
1251         ctx->dev = dev;
1252         ctx->vp_enabled = drv->is_vp_enabled;
1253         ctx->mxr_ver = drv->version;
1254         init_waitqueue_head(&ctx->wait_vsync_queue);
1255         atomic_set(&ctx->wait_vsync_event, 0);
1256
1257         mixer_manager.ctx = ctx;
1258         ret = mixer_initialize(&mixer_manager, drm_dev);
1259         if (ret)
1260                 return ret;
1261
1262         platform_set_drvdata(pdev, &mixer_manager);
1263         ret = exynos_drm_crtc_create(&mixer_manager);
1264         if (ret) {
1265                 mixer_mgr_remove(&mixer_manager);
1266                 return ret;
1267         }
1268
1269         pm_runtime_enable(dev);
1270
1271         return 0;
1272 }
1273
1274 static void mixer_unbind(struct device *dev, struct device *master, void *data)
1275 {
1276         struct exynos_drm_manager *mgr = dev_get_drvdata(dev);
1277         struct drm_crtc *crtc = mgr->crtc;
1278
1279         dev_info(dev, "remove successful\n");
1280
1281         mixer_mgr_remove(mgr);
1282
1283         pm_runtime_disable(dev);
1284
1285         crtc->funcs->destroy(crtc);
1286 }
1287
1288 static const struct component_ops mixer_component_ops = {
1289         .bind   = mixer_bind,
1290         .unbind = mixer_unbind,
1291 };
1292
1293 static int mixer_probe(struct platform_device *pdev)
1294 {
1295         int ret;
1296
1297         ret = exynos_drm_component_add(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC,
1298                                         mixer_manager.type);
1299         if (ret)
1300                 return ret;
1301
1302         ret = component_add(&pdev->dev, &mixer_component_ops);
1303         if (ret)
1304                 exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC);
1305
1306         return ret;
1307 }
1308
1309 static int mixer_remove(struct platform_device *pdev)
1310 {
1311         component_del(&pdev->dev, &mixer_component_ops);
1312         exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC);
1313
1314         return 0;
1315 }
1316
1317 struct platform_driver mixer_driver = {
1318         .driver = {
1319                 .name = "exynos-mixer",
1320                 .owner = THIS_MODULE,
1321                 .of_match_table = mixer_match_types,
1322         },
1323         .probe = mixer_probe,
1324         .remove = mixer_remove,
1325         .id_table       = mixer_driver_types,
1326 };