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