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