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