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