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