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