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