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