Version:  2.0.40 2.2.26 2.4.37 3.12 3.13 3.14 3.15 3.16 3.17 3.18 3.19 4.0 4.1 4.2 4.3 4.4 4.5 4.6 4.7 4.8 4.9

Linux/drivers/gpu/drm/exynos/exynos_mixer.c

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

This page was automatically generated by LXR 0.3.1 (source).  •  Linux is a registered trademark of Linus Torvalds  •  Contact us