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