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