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