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