]> Pileus Git - ~andy/linux/blob - drivers/gpu/drm/exynos/exynos_mixer.c
drm/nouveau/bios: parse fan bump/slow periods, and trip points
[~andy/linux] / 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 void mixer_wait_for_vblank(void *ctx)
822 {
823         struct mixer_context *mixer_ctx = ctx;
824
825         mutex_lock(&mixer_ctx->mixer_mutex);
826         if (!mixer_ctx->powered) {
827                 mutex_unlock(&mixer_ctx->mixer_mutex);
828                 return;
829         }
830         mutex_unlock(&mixer_ctx->mixer_mutex);
831
832         atomic_set(&mixer_ctx->wait_vsync_event, 1);
833
834         /*
835          * wait for MIXER to signal VSYNC interrupt or return after
836          * timeout which is set to 50ms (refresh rate of 20).
837          */
838         if (!wait_event_timeout(mixer_ctx->wait_vsync_queue,
839                                 !atomic_read(&mixer_ctx->wait_vsync_event),
840                                 DRM_HZ/20))
841                 DRM_DEBUG_KMS("vblank wait timed out.\n");
842 }
843
844 static void mixer_window_suspend(struct mixer_context *ctx)
845 {
846         struct hdmi_win_data *win_data;
847         int i;
848
849         for (i = 0; i < MIXER_WIN_NR; i++) {
850                 win_data = &ctx->win_data[i];
851                 win_data->resume = win_data->enabled;
852                 mixer_win_disable(ctx, i);
853         }
854         mixer_wait_for_vblank(ctx);
855 }
856
857 static void mixer_window_resume(struct mixer_context *ctx)
858 {
859         struct hdmi_win_data *win_data;
860         int i;
861
862         for (i = 0; i < MIXER_WIN_NR; i++) {
863                 win_data = &ctx->win_data[i];
864                 win_data->enabled = win_data->resume;
865                 win_data->resume = false;
866         }
867 }
868
869 static void mixer_poweron(struct mixer_context *ctx)
870 {
871         struct mixer_resources *res = &ctx->mixer_res;
872
873         DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
874
875         mutex_lock(&ctx->mixer_mutex);
876         if (ctx->powered) {
877                 mutex_unlock(&ctx->mixer_mutex);
878                 return;
879         }
880         ctx->powered = true;
881         mutex_unlock(&ctx->mixer_mutex);
882
883         clk_enable(res->mixer);
884         if (ctx->vp_enabled) {
885                 clk_enable(res->vp);
886                 clk_enable(res->sclk_mixer);
887         }
888
889         mixer_reg_write(res, MXR_INT_EN, ctx->int_en);
890         mixer_win_reset(ctx);
891
892         mixer_window_resume(ctx);
893 }
894
895 static void mixer_poweroff(struct mixer_context *ctx)
896 {
897         struct mixer_resources *res = &ctx->mixer_res;
898
899         DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
900
901         mutex_lock(&ctx->mixer_mutex);
902         if (!ctx->powered)
903                 goto out;
904         mutex_unlock(&ctx->mixer_mutex);
905
906         mixer_window_suspend(ctx);
907
908         ctx->int_en = mixer_reg_read(res, MXR_INT_EN);
909
910         clk_disable(res->mixer);
911         if (ctx->vp_enabled) {
912                 clk_disable(res->vp);
913                 clk_disable(res->sclk_mixer);
914         }
915
916         mutex_lock(&ctx->mixer_mutex);
917         ctx->powered = false;
918
919 out:
920         mutex_unlock(&ctx->mixer_mutex);
921 }
922
923 static void mixer_dpms(void *ctx, int mode)
924 {
925         struct mixer_context *mixer_ctx = ctx;
926
927         DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
928
929         switch (mode) {
930         case DRM_MODE_DPMS_ON:
931                 if (pm_runtime_suspended(mixer_ctx->dev))
932                         pm_runtime_get_sync(mixer_ctx->dev);
933                 break;
934         case DRM_MODE_DPMS_STANDBY:
935         case DRM_MODE_DPMS_SUSPEND:
936         case DRM_MODE_DPMS_OFF:
937                 if (!pm_runtime_suspended(mixer_ctx->dev))
938                         pm_runtime_put_sync(mixer_ctx->dev);
939                 break;
940         default:
941                 DRM_DEBUG_KMS("unknown dpms mode: %d\n", mode);
942                 break;
943         }
944 }
945
946 static struct exynos_mixer_ops mixer_ops = {
947         /* manager */
948         .iommu_on               = mixer_iommu_on,
949         .enable_vblank          = mixer_enable_vblank,
950         .disable_vblank         = mixer_disable_vblank,
951         .wait_for_vblank        = mixer_wait_for_vblank,
952         .dpms                   = mixer_dpms,
953
954         /* overlay */
955         .win_mode_set           = mixer_win_mode_set,
956         .win_commit             = mixer_win_commit,
957         .win_disable            = mixer_win_disable,
958 };
959
960 static irqreturn_t mixer_irq_handler(int irq, void *arg)
961 {
962         struct exynos_drm_hdmi_context *drm_hdmi_ctx = arg;
963         struct mixer_context *ctx = drm_hdmi_ctx->ctx;
964         struct mixer_resources *res = &ctx->mixer_res;
965         u32 val, base, shadow;
966
967         spin_lock(&res->reg_slock);
968
969         /* read interrupt status for handling and clearing flags for VSYNC */
970         val = mixer_reg_read(res, MXR_INT_STATUS);
971
972         /* handling VSYNC */
973         if (val & MXR_INT_STATUS_VSYNC) {
974                 /* interlace scan need to check shadow register */
975                 if (ctx->interlace) {
976                         base = mixer_reg_read(res, MXR_GRAPHIC_BASE(0));
977                         shadow = mixer_reg_read(res, MXR_GRAPHIC_BASE_S(0));
978                         if (base != shadow)
979                                 goto out;
980
981                         base = mixer_reg_read(res, MXR_GRAPHIC_BASE(1));
982                         shadow = mixer_reg_read(res, MXR_GRAPHIC_BASE_S(1));
983                         if (base != shadow)
984                                 goto out;
985                 }
986
987                 drm_handle_vblank(drm_hdmi_ctx->drm_dev, ctx->pipe);
988                 exynos_drm_crtc_finish_pageflip(drm_hdmi_ctx->drm_dev,
989                                 ctx->pipe);
990
991                 /* set wait vsync event to zero and wake up queue. */
992                 if (atomic_read(&ctx->wait_vsync_event)) {
993                         atomic_set(&ctx->wait_vsync_event, 0);
994                         DRM_WAKEUP(&ctx->wait_vsync_queue);
995                 }
996         }
997
998 out:
999         /* clear interrupts */
1000         if (~val & MXR_INT_EN_VSYNC) {
1001                 /* vsync interrupt use different bit for read and clear */
1002                 val &= ~MXR_INT_EN_VSYNC;
1003                 val |= MXR_INT_CLEAR_VSYNC;
1004         }
1005         mixer_reg_write(res, MXR_INT_STATUS, val);
1006
1007         spin_unlock(&res->reg_slock);
1008
1009         return IRQ_HANDLED;
1010 }
1011
1012 static int mixer_resources_init(struct exynos_drm_hdmi_context *ctx,
1013                                 struct platform_device *pdev)
1014 {
1015         struct mixer_context *mixer_ctx = ctx->ctx;
1016         struct device *dev = &pdev->dev;
1017         struct mixer_resources *mixer_res = &mixer_ctx->mixer_res;
1018         struct resource *res;
1019         int ret;
1020
1021         spin_lock_init(&mixer_res->reg_slock);
1022
1023         mixer_res->mixer = devm_clk_get(dev, "mixer");
1024         if (IS_ERR_OR_NULL(mixer_res->mixer)) {
1025                 dev_err(dev, "failed to get clock 'mixer'\n");
1026                 return -ENODEV;
1027         }
1028
1029         mixer_res->sclk_hdmi = devm_clk_get(dev, "sclk_hdmi");
1030         if (IS_ERR_OR_NULL(mixer_res->sclk_hdmi)) {
1031                 dev_err(dev, "failed to get clock 'sclk_hdmi'\n");
1032                 return -ENODEV;
1033         }
1034         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1035         if (res == NULL) {
1036                 dev_err(dev, "get memory resource failed.\n");
1037                 return -ENXIO;
1038         }
1039
1040         mixer_res->mixer_regs = devm_ioremap(&pdev->dev, res->start,
1041                                                         resource_size(res));
1042         if (mixer_res->mixer_regs == NULL) {
1043                 dev_err(dev, "register mapping failed.\n");
1044                 return -ENXIO;
1045         }
1046
1047         res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
1048         if (res == NULL) {
1049                 dev_err(dev, "get interrupt resource failed.\n");
1050                 return -ENXIO;
1051         }
1052
1053         ret = devm_request_irq(&pdev->dev, res->start, mixer_irq_handler,
1054                                                         0, "drm_mixer", ctx);
1055         if (ret) {
1056                 dev_err(dev, "request interrupt failed.\n");
1057                 return ret;
1058         }
1059         mixer_res->irq = res->start;
1060
1061         return 0;
1062 }
1063
1064 static int vp_resources_init(struct exynos_drm_hdmi_context *ctx,
1065                              struct platform_device *pdev)
1066 {
1067         struct mixer_context *mixer_ctx = ctx->ctx;
1068         struct device *dev = &pdev->dev;
1069         struct mixer_resources *mixer_res = &mixer_ctx->mixer_res;
1070         struct resource *res;
1071
1072         mixer_res->vp = devm_clk_get(dev, "vp");
1073         if (IS_ERR_OR_NULL(mixer_res->vp)) {
1074                 dev_err(dev, "failed to get clock 'vp'\n");
1075                 return -ENODEV;
1076         }
1077         mixer_res->sclk_mixer = devm_clk_get(dev, "sclk_mixer");
1078         if (IS_ERR_OR_NULL(mixer_res->sclk_mixer)) {
1079                 dev_err(dev, "failed to get clock 'sclk_mixer'\n");
1080                 return -ENODEV;
1081         }
1082         mixer_res->sclk_dac = devm_clk_get(dev, "sclk_dac");
1083         if (IS_ERR_OR_NULL(mixer_res->sclk_dac)) {
1084                 dev_err(dev, "failed to get clock 'sclk_dac'\n");
1085                 return -ENODEV;
1086         }
1087
1088         if (mixer_res->sclk_hdmi)
1089                 clk_set_parent(mixer_res->sclk_mixer, mixer_res->sclk_hdmi);
1090
1091         res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
1092         if (res == NULL) {
1093                 dev_err(dev, "get memory resource failed.\n");
1094                 return -ENXIO;
1095         }
1096
1097         mixer_res->vp_regs = devm_ioremap(&pdev->dev, res->start,
1098                                                         resource_size(res));
1099         if (mixer_res->vp_regs == NULL) {
1100                 dev_err(dev, "register mapping failed.\n");
1101                 return -ENXIO;
1102         }
1103
1104         return 0;
1105 }
1106
1107 static struct mixer_drv_data exynos5_mxr_drv_data = {
1108         .version = MXR_VER_16_0_33_0,
1109         .is_vp_enabled = 0,
1110 };
1111
1112 static struct mixer_drv_data exynos4_mxr_drv_data = {
1113         .version = MXR_VER_0_0_0_16,
1114         .is_vp_enabled = 1,
1115 };
1116
1117 static struct platform_device_id mixer_driver_types[] = {
1118         {
1119                 .name           = "s5p-mixer",
1120                 .driver_data    = (unsigned long)&exynos4_mxr_drv_data,
1121         }, {
1122                 .name           = "exynos5-mixer",
1123                 .driver_data    = (unsigned long)&exynos5_mxr_drv_data,
1124         }, {
1125                 /* end node */
1126         }
1127 };
1128
1129 static struct of_device_id mixer_match_types[] = {
1130         {
1131                 .compatible = "samsung,exynos5-mixer",
1132                 .data   = &exynos5_mxr_drv_data,
1133         }, {
1134                 /* end node */
1135         }
1136 };
1137
1138 static int mixer_probe(struct platform_device *pdev)
1139 {
1140         struct device *dev = &pdev->dev;
1141         struct exynos_drm_hdmi_context *drm_hdmi_ctx;
1142         struct mixer_context *ctx;
1143         struct mixer_drv_data *drv;
1144         int ret;
1145
1146         dev_info(dev, "probe start\n");
1147
1148         drm_hdmi_ctx = devm_kzalloc(&pdev->dev, sizeof(*drm_hdmi_ctx),
1149                                                                 GFP_KERNEL);
1150         if (!drm_hdmi_ctx) {
1151                 DRM_ERROR("failed to allocate common hdmi context.\n");
1152                 return -ENOMEM;
1153         }
1154
1155         ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
1156         if (!ctx) {
1157                 DRM_ERROR("failed to alloc mixer context.\n");
1158                 return -ENOMEM;
1159         }
1160
1161         mutex_init(&ctx->mixer_mutex);
1162
1163         if (dev->of_node) {
1164                 const struct of_device_id *match;
1165                 match = of_match_node(of_match_ptr(mixer_match_types),
1166                                                           pdev->dev.of_node);
1167                 drv = (struct mixer_drv_data *)match->data;
1168         } else {
1169                 drv = (struct mixer_drv_data *)
1170                         platform_get_device_id(pdev)->driver_data;
1171         }
1172
1173         ctx->dev = &pdev->dev;
1174         ctx->parent_ctx = (void *)drm_hdmi_ctx;
1175         drm_hdmi_ctx->ctx = (void *)ctx;
1176         ctx->vp_enabled = drv->is_vp_enabled;
1177         ctx->mxr_ver = drv->version;
1178         DRM_INIT_WAITQUEUE(&ctx->wait_vsync_queue);
1179         atomic_set(&ctx->wait_vsync_event, 0);
1180
1181         platform_set_drvdata(pdev, drm_hdmi_ctx);
1182
1183         /* acquire resources: regs, irqs, clocks */
1184         ret = mixer_resources_init(drm_hdmi_ctx, pdev);
1185         if (ret) {
1186                 DRM_ERROR("mixer_resources_init failed\n");
1187                 goto fail;
1188         }
1189
1190         if (ctx->vp_enabled) {
1191                 /* acquire vp resources: regs, irqs, clocks */
1192                 ret = vp_resources_init(drm_hdmi_ctx, pdev);
1193                 if (ret) {
1194                         DRM_ERROR("vp_resources_init failed\n");
1195                         goto fail;
1196                 }
1197         }
1198
1199         /* attach mixer driver to common hdmi. */
1200         exynos_mixer_drv_attach(drm_hdmi_ctx);
1201
1202         /* register specific callback point to common hdmi. */
1203         exynos_mixer_ops_register(&mixer_ops);
1204
1205         pm_runtime_enable(dev);
1206
1207         return 0;
1208
1209
1210 fail:
1211         dev_info(dev, "probe failed\n");
1212         return ret;
1213 }
1214
1215 static int mixer_remove(struct platform_device *pdev)
1216 {
1217         dev_info(&pdev->dev, "remove successful\n");
1218
1219         pm_runtime_disable(&pdev->dev);
1220
1221         return 0;
1222 }
1223
1224 #ifdef CONFIG_PM_SLEEP
1225 static int mixer_suspend(struct device *dev)
1226 {
1227         struct exynos_drm_hdmi_context *drm_hdmi_ctx = get_mixer_context(dev);
1228         struct mixer_context *ctx = drm_hdmi_ctx->ctx;
1229
1230         DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
1231
1232         if (pm_runtime_suspended(dev)) {
1233                 DRM_DEBUG_KMS("%s : Already suspended\n", __func__);
1234                 return 0;
1235         }
1236
1237         mixer_poweroff(ctx);
1238
1239         return 0;
1240 }
1241
1242 static int mixer_resume(struct device *dev)
1243 {
1244         struct exynos_drm_hdmi_context *drm_hdmi_ctx = get_mixer_context(dev);
1245         struct mixer_context *ctx = drm_hdmi_ctx->ctx;
1246
1247         DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
1248
1249         if (!pm_runtime_suspended(dev)) {
1250                 DRM_DEBUG_KMS("%s : Already resumed\n", __func__);
1251                 return 0;
1252         }
1253
1254         mixer_poweron(ctx);
1255
1256         return 0;
1257 }
1258 #endif
1259
1260 #ifdef CONFIG_PM_RUNTIME
1261 static int mixer_runtime_suspend(struct device *dev)
1262 {
1263         struct exynos_drm_hdmi_context *drm_hdmi_ctx = get_mixer_context(dev);
1264         struct mixer_context *ctx = drm_hdmi_ctx->ctx;
1265
1266         DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
1267
1268         mixer_poweroff(ctx);
1269
1270         return 0;
1271 }
1272
1273 static int mixer_runtime_resume(struct device *dev)
1274 {
1275         struct exynos_drm_hdmi_context *drm_hdmi_ctx = get_mixer_context(dev);
1276         struct mixer_context *ctx = drm_hdmi_ctx->ctx;
1277
1278         DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
1279
1280         mixer_poweron(ctx);
1281
1282         return 0;
1283 }
1284 #endif
1285
1286 static const struct dev_pm_ops mixer_pm_ops = {
1287         SET_SYSTEM_SLEEP_PM_OPS(mixer_suspend, mixer_resume)
1288         SET_RUNTIME_PM_OPS(mixer_runtime_suspend, mixer_runtime_resume, NULL)
1289 };
1290
1291 struct platform_driver mixer_driver = {
1292         .driver = {
1293                 .name = "exynos-mixer",
1294                 .owner = THIS_MODULE,
1295                 .pm = &mixer_pm_ops,
1296                 .of_match_table = mixer_match_types,
1297         },
1298         .probe = mixer_probe,
1299         .remove = mixer_remove,
1300         .id_table       = mixer_driver_types,
1301 };