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