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