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