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