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