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