Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * Copyright (C) 2011 Samsung Electronics Co.Ltd
0004  * Authors:
0005  * Seung-Woo Kim <sw0312.kim@samsung.com>
0006  *  Inki Dae <inki.dae@samsung.com>
0007  *  Joonyoung Shim <jy0922.shim@samsung.com>
0008  *
0009  * Based on drivers/media/video/s5p-tv/mixer_reg.c
0010  */
0011 
0012 #include <linux/clk.h>
0013 #include <linux/component.h>
0014 #include <linux/delay.h>
0015 #include <linux/i2c.h>
0016 #include <linux/interrupt.h>
0017 #include <linux/irq.h>
0018 #include <linux/kernel.h>
0019 #include <linux/ktime.h>
0020 #include <linux/of.h>
0021 #include <linux/of_device.h>
0022 #include <linux/platform_device.h>
0023 #include <linux/pm_runtime.h>
0024 #include <linux/regulator/consumer.h>
0025 #include <linux/spinlock.h>
0026 #include <linux/wait.h>
0027 
0028 #include <drm/drm_blend.h>
0029 #include <drm/drm_edid.h>
0030 #include <drm/drm_fourcc.h>
0031 #include <drm/drm_framebuffer.h>
0032 #include <drm/drm_vblank.h>
0033 #include <drm/exynos_drm.h>
0034 
0035 #include "exynos_drm_crtc.h"
0036 #include "exynos_drm_drv.h"
0037 #include "exynos_drm_fb.h"
0038 #include "exynos_drm_plane.h"
0039 #include "regs-mixer.h"
0040 #include "regs-vp.h"
0041 
0042 #define MIXER_WIN_NR        3
0043 #define VP_DEFAULT_WIN      2
0044 
0045 /*
0046  * Mixer color space conversion coefficient triplet.
0047  * Used for CSC from RGB to YCbCr.
0048  * Each coefficient is a 10-bit fixed point number with
0049  * sign and no integer part, i.e.
0050  * [0:8] = fractional part (representing a value y = x / 2^9)
0051  * [9] = sign
0052  * Negative values are encoded with two's complement.
0053  */
0054 #define MXR_CSC_C(x) ((int)((x) * 512.0) & 0x3ff)
0055 #define MXR_CSC_CT(a0, a1, a2) \
0056   ((MXR_CSC_C(a0) << 20) | (MXR_CSC_C(a1) << 10) | (MXR_CSC_C(a2) << 0))
0057 
0058 /* YCbCr value, used for mixer background color configuration. */
0059 #define MXR_YCBCR_VAL(y, cb, cr) (((y) << 16) | ((cb) << 8) | ((cr) << 0))
0060 
0061 /* The pixelformats that are natively supported by the mixer. */
0062 #define MXR_FORMAT_RGB565   4
0063 #define MXR_FORMAT_ARGB1555 5
0064 #define MXR_FORMAT_ARGB4444 6
0065 #define MXR_FORMAT_ARGB8888 7
0066 
0067 enum mixer_version_id {
0068     MXR_VER_0_0_0_16,
0069     MXR_VER_16_0_33_0,
0070     MXR_VER_128_0_0_184,
0071 };
0072 
0073 enum mixer_flag_bits {
0074     MXR_BIT_POWERED,
0075     MXR_BIT_VSYNC,
0076     MXR_BIT_INTERLACE,
0077     MXR_BIT_VP_ENABLED,
0078     MXR_BIT_HAS_SCLK,
0079 };
0080 
0081 static const uint32_t mixer_formats[] = {
0082     DRM_FORMAT_XRGB4444,
0083     DRM_FORMAT_ARGB4444,
0084     DRM_FORMAT_XRGB1555,
0085     DRM_FORMAT_ARGB1555,
0086     DRM_FORMAT_RGB565,
0087     DRM_FORMAT_XRGB8888,
0088     DRM_FORMAT_ARGB8888,
0089 };
0090 
0091 static const uint32_t vp_formats[] = {
0092     DRM_FORMAT_NV12,
0093     DRM_FORMAT_NV21,
0094 };
0095 
0096 struct mixer_context {
0097     struct platform_device *pdev;
0098     struct device       *dev;
0099     struct drm_device   *drm_dev;
0100     void            *dma_priv;
0101     struct exynos_drm_crtc  *crtc;
0102     struct exynos_drm_plane planes[MIXER_WIN_NR];
0103     unsigned long       flags;
0104 
0105     int         irq;
0106     void __iomem        *mixer_regs;
0107     void __iomem        *vp_regs;
0108     spinlock_t      reg_slock;
0109     struct clk      *mixer;
0110     struct clk      *vp;
0111     struct clk      *hdmi;
0112     struct clk      *sclk_mixer;
0113     struct clk      *sclk_hdmi;
0114     struct clk      *mout_mixer;
0115     enum mixer_version_id   mxr_ver;
0116     int         scan_value;
0117 };
0118 
0119 struct mixer_drv_data {
0120     enum mixer_version_id   version;
0121     bool                    is_vp_enabled;
0122     bool                    has_sclk;
0123 };
0124 
0125 static const struct exynos_drm_plane_config plane_configs[MIXER_WIN_NR] = {
0126     {
0127         .zpos = 0,
0128         .type = DRM_PLANE_TYPE_PRIMARY,
0129         .pixel_formats = mixer_formats,
0130         .num_pixel_formats = ARRAY_SIZE(mixer_formats),
0131         .capabilities = EXYNOS_DRM_PLANE_CAP_DOUBLE |
0132                 EXYNOS_DRM_PLANE_CAP_ZPOS |
0133                 EXYNOS_DRM_PLANE_CAP_PIX_BLEND |
0134                 EXYNOS_DRM_PLANE_CAP_WIN_BLEND,
0135     }, {
0136         .zpos = 1,
0137         .type = DRM_PLANE_TYPE_CURSOR,
0138         .pixel_formats = mixer_formats,
0139         .num_pixel_formats = ARRAY_SIZE(mixer_formats),
0140         .capabilities = EXYNOS_DRM_PLANE_CAP_DOUBLE |
0141                 EXYNOS_DRM_PLANE_CAP_ZPOS |
0142                 EXYNOS_DRM_PLANE_CAP_PIX_BLEND |
0143                 EXYNOS_DRM_PLANE_CAP_WIN_BLEND,
0144     }, {
0145         .zpos = 2,
0146         .type = DRM_PLANE_TYPE_OVERLAY,
0147         .pixel_formats = vp_formats,
0148         .num_pixel_formats = ARRAY_SIZE(vp_formats),
0149         .capabilities = EXYNOS_DRM_PLANE_CAP_SCALE |
0150                 EXYNOS_DRM_PLANE_CAP_ZPOS |
0151                 EXYNOS_DRM_PLANE_CAP_TILE |
0152                 EXYNOS_DRM_PLANE_CAP_WIN_BLEND,
0153     },
0154 };
0155 
0156 static const u8 filter_y_horiz_tap8[] = {
0157     0,  -1, -1, -1, -1, -1, -1, -1,
0158     -1, -1, -1, -1, -1, 0,  0,  0,
0159     0,  2,  4,  5,  6,  6,  6,  6,
0160     6,  5,  5,  4,  3,  2,  1,  1,
0161     0,  -6, -12,    -16,    -18,    -20,    -21,    -20,
0162     -20,    -18,    -16,    -13,    -10,    -8, -5, -2,
0163     127,    126,    125,    121,    114,    107,    99, 89,
0164     79, 68, 57, 46, 35, 25, 16, 8,
0165 };
0166 
0167 static const u8 filter_y_vert_tap4[] = {
0168     0,  -3, -6, -8, -8, -8, -8, -7,
0169     -6, -5, -4, -3, -2, -1, -1, 0,
0170     127,    126,    124,    118,    111,    102,    92, 81,
0171     70, 59, 48, 37, 27, 19, 11, 5,
0172     0,  5,  11, 19, 27, 37, 48, 59,
0173     70, 81, 92, 102,    111,    118,    124,    126,
0174     0,  0,  -1, -1, -2, -3, -4, -5,
0175     -6, -7, -8, -8, -8, -8, -6, -3,
0176 };
0177 
0178 static const u8 filter_cr_horiz_tap4[] = {
0179     0,  -3, -6, -8, -8, -8, -8, -7,
0180     -6, -5, -4, -3, -2, -1, -1, 0,
0181     127,    126,    124,    118,    111,    102,    92, 81,
0182     70, 59, 48, 37, 27, 19, 11, 5,
0183 };
0184 
0185 static inline u32 vp_reg_read(struct mixer_context *ctx, u32 reg_id)
0186 {
0187     return readl(ctx->vp_regs + reg_id);
0188 }
0189 
0190 static inline void vp_reg_write(struct mixer_context *ctx, u32 reg_id,
0191                  u32 val)
0192 {
0193     writel(val, ctx->vp_regs + reg_id);
0194 }
0195 
0196 static inline void vp_reg_writemask(struct mixer_context *ctx, u32 reg_id,
0197                  u32 val, u32 mask)
0198 {
0199     u32 old = vp_reg_read(ctx, reg_id);
0200 
0201     val = (val & mask) | (old & ~mask);
0202     writel(val, ctx->vp_regs + reg_id);
0203 }
0204 
0205 static inline u32 mixer_reg_read(struct mixer_context *ctx, u32 reg_id)
0206 {
0207     return readl(ctx->mixer_regs + reg_id);
0208 }
0209 
0210 static inline void mixer_reg_write(struct mixer_context *ctx, u32 reg_id,
0211                  u32 val)
0212 {
0213     writel(val, ctx->mixer_regs + reg_id);
0214 }
0215 
0216 static inline void mixer_reg_writemask(struct mixer_context *ctx,
0217                  u32 reg_id, u32 val, u32 mask)
0218 {
0219     u32 old = mixer_reg_read(ctx, reg_id);
0220 
0221     val = (val & mask) | (old & ~mask);
0222     writel(val, ctx->mixer_regs + reg_id);
0223 }
0224 
0225 static void mixer_regs_dump(struct mixer_context *ctx)
0226 {
0227 #define DUMPREG(reg_id) \
0228 do { \
0229     DRM_DEV_DEBUG_KMS(ctx->dev, #reg_id " = %08x\n", \
0230              (u32)readl(ctx->mixer_regs + reg_id)); \
0231 } while (0)
0232 
0233     DUMPREG(MXR_STATUS);
0234     DUMPREG(MXR_CFG);
0235     DUMPREG(MXR_INT_EN);
0236     DUMPREG(MXR_INT_STATUS);
0237 
0238     DUMPREG(MXR_LAYER_CFG);
0239     DUMPREG(MXR_VIDEO_CFG);
0240 
0241     DUMPREG(MXR_GRAPHIC0_CFG);
0242     DUMPREG(MXR_GRAPHIC0_BASE);
0243     DUMPREG(MXR_GRAPHIC0_SPAN);
0244     DUMPREG(MXR_GRAPHIC0_WH);
0245     DUMPREG(MXR_GRAPHIC0_SXY);
0246     DUMPREG(MXR_GRAPHIC0_DXY);
0247 
0248     DUMPREG(MXR_GRAPHIC1_CFG);
0249     DUMPREG(MXR_GRAPHIC1_BASE);
0250     DUMPREG(MXR_GRAPHIC1_SPAN);
0251     DUMPREG(MXR_GRAPHIC1_WH);
0252     DUMPREG(MXR_GRAPHIC1_SXY);
0253     DUMPREG(MXR_GRAPHIC1_DXY);
0254 #undef DUMPREG
0255 }
0256 
0257 static void vp_regs_dump(struct mixer_context *ctx)
0258 {
0259 #define DUMPREG(reg_id) \
0260 do { \
0261     DRM_DEV_DEBUG_KMS(ctx->dev, #reg_id " = %08x\n", \
0262              (u32) readl(ctx->vp_regs + reg_id)); \
0263 } while (0)
0264 
0265     DUMPREG(VP_ENABLE);
0266     DUMPREG(VP_SRESET);
0267     DUMPREG(VP_SHADOW_UPDATE);
0268     DUMPREG(VP_FIELD_ID);
0269     DUMPREG(VP_MODE);
0270     DUMPREG(VP_IMG_SIZE_Y);
0271     DUMPREG(VP_IMG_SIZE_C);
0272     DUMPREG(VP_PER_RATE_CTRL);
0273     DUMPREG(VP_TOP_Y_PTR);
0274     DUMPREG(VP_BOT_Y_PTR);
0275     DUMPREG(VP_TOP_C_PTR);
0276     DUMPREG(VP_BOT_C_PTR);
0277     DUMPREG(VP_ENDIAN_MODE);
0278     DUMPREG(VP_SRC_H_POSITION);
0279     DUMPREG(VP_SRC_V_POSITION);
0280     DUMPREG(VP_SRC_WIDTH);
0281     DUMPREG(VP_SRC_HEIGHT);
0282     DUMPREG(VP_DST_H_POSITION);
0283     DUMPREG(VP_DST_V_POSITION);
0284     DUMPREG(VP_DST_WIDTH);
0285     DUMPREG(VP_DST_HEIGHT);
0286     DUMPREG(VP_H_RATIO);
0287     DUMPREG(VP_V_RATIO);
0288 
0289 #undef DUMPREG
0290 }
0291 
0292 static inline void vp_filter_set(struct mixer_context *ctx,
0293         int reg_id, const u8 *data, unsigned int size)
0294 {
0295     /* assure 4-byte align */
0296     BUG_ON(size & 3);
0297     for (; size; size -= 4, reg_id += 4, data += 4) {
0298         u32 val = (data[0] << 24) |  (data[1] << 16) |
0299             (data[2] << 8) | data[3];
0300         vp_reg_write(ctx, reg_id, val);
0301     }
0302 }
0303 
0304 static void vp_default_filter(struct mixer_context *ctx)
0305 {
0306     vp_filter_set(ctx, VP_POLY8_Y0_LL,
0307         filter_y_horiz_tap8, sizeof(filter_y_horiz_tap8));
0308     vp_filter_set(ctx, VP_POLY4_Y0_LL,
0309         filter_y_vert_tap4, sizeof(filter_y_vert_tap4));
0310     vp_filter_set(ctx, VP_POLY4_C0_LL,
0311         filter_cr_horiz_tap4, sizeof(filter_cr_horiz_tap4));
0312 }
0313 
0314 static void mixer_cfg_gfx_blend(struct mixer_context *ctx, unsigned int win,
0315                 unsigned int pixel_alpha, unsigned int alpha)
0316 {
0317     u32 win_alpha = alpha >> 8;
0318     u32 val;
0319 
0320     val  = MXR_GRP_CFG_COLOR_KEY_DISABLE; /* no blank key */
0321     switch (pixel_alpha) {
0322     case DRM_MODE_BLEND_PIXEL_NONE:
0323         break;
0324     case DRM_MODE_BLEND_COVERAGE:
0325         val |= MXR_GRP_CFG_PIXEL_BLEND_EN;
0326         break;
0327     case DRM_MODE_BLEND_PREMULTI:
0328     default:
0329         val |= MXR_GRP_CFG_BLEND_PRE_MUL;
0330         val |= MXR_GRP_CFG_PIXEL_BLEND_EN;
0331         break;
0332     }
0333 
0334     if (alpha != DRM_BLEND_ALPHA_OPAQUE) {
0335         val |= MXR_GRP_CFG_WIN_BLEND_EN;
0336         val |= win_alpha;
0337     }
0338     mixer_reg_writemask(ctx, MXR_GRAPHIC_CFG(win),
0339                 val, MXR_GRP_CFG_MISC_MASK);
0340 }
0341 
0342 static void mixer_cfg_vp_blend(struct mixer_context *ctx, unsigned int alpha)
0343 {
0344     u32 win_alpha = alpha >> 8;
0345     u32 val = 0;
0346 
0347     if (alpha != DRM_BLEND_ALPHA_OPAQUE) {
0348         val |= MXR_VID_CFG_BLEND_EN;
0349         val |= win_alpha;
0350     }
0351     mixer_reg_write(ctx, MXR_VIDEO_CFG, val);
0352 }
0353 
0354 static bool mixer_is_synced(struct mixer_context *ctx)
0355 {
0356     u32 base, shadow;
0357 
0358     if (ctx->mxr_ver == MXR_VER_16_0_33_0 ||
0359         ctx->mxr_ver == MXR_VER_128_0_0_184)
0360         return !(mixer_reg_read(ctx, MXR_CFG) &
0361              MXR_CFG_LAYER_UPDATE_COUNT_MASK);
0362 
0363     if (test_bit(MXR_BIT_VP_ENABLED, &ctx->flags) &&
0364         vp_reg_read(ctx, VP_SHADOW_UPDATE))
0365         return false;
0366 
0367     base = mixer_reg_read(ctx, MXR_CFG);
0368     shadow = mixer_reg_read(ctx, MXR_CFG_S);
0369     if (base != shadow)
0370         return false;
0371 
0372     base = mixer_reg_read(ctx, MXR_GRAPHIC_BASE(0));
0373     shadow = mixer_reg_read(ctx, MXR_GRAPHIC_BASE_S(0));
0374     if (base != shadow)
0375         return false;
0376 
0377     base = mixer_reg_read(ctx, MXR_GRAPHIC_BASE(1));
0378     shadow = mixer_reg_read(ctx, MXR_GRAPHIC_BASE_S(1));
0379     if (base != shadow)
0380         return false;
0381 
0382     return true;
0383 }
0384 
0385 static int mixer_wait_for_sync(struct mixer_context *ctx)
0386 {
0387     ktime_t timeout = ktime_add_us(ktime_get(), 100000);
0388 
0389     while (!mixer_is_synced(ctx)) {
0390         usleep_range(1000, 2000);
0391         if (ktime_compare(ktime_get(), timeout) > 0)
0392             return -ETIMEDOUT;
0393     }
0394     return 0;
0395 }
0396 
0397 static void mixer_disable_sync(struct mixer_context *ctx)
0398 {
0399     mixer_reg_writemask(ctx, MXR_STATUS, 0, MXR_STATUS_SYNC_ENABLE);
0400 }
0401 
0402 static void mixer_enable_sync(struct mixer_context *ctx)
0403 {
0404     if (ctx->mxr_ver == MXR_VER_16_0_33_0 ||
0405         ctx->mxr_ver == MXR_VER_128_0_0_184)
0406         mixer_reg_writemask(ctx, MXR_CFG, ~0, MXR_CFG_LAYER_UPDATE);
0407     mixer_reg_writemask(ctx, MXR_STATUS, ~0, MXR_STATUS_SYNC_ENABLE);
0408     if (test_bit(MXR_BIT_VP_ENABLED, &ctx->flags))
0409         vp_reg_write(ctx, VP_SHADOW_UPDATE, VP_SHADOW_UPDATE_ENABLE);
0410 }
0411 
0412 static void mixer_cfg_scan(struct mixer_context *ctx, int width, int height)
0413 {
0414     u32 val;
0415 
0416     /* choosing between interlace and progressive mode */
0417     val = test_bit(MXR_BIT_INTERLACE, &ctx->flags) ?
0418         MXR_CFG_SCAN_INTERLACE : MXR_CFG_SCAN_PROGRESSIVE;
0419 
0420     if (ctx->mxr_ver == MXR_VER_128_0_0_184)
0421         mixer_reg_write(ctx, MXR_RESOLUTION,
0422             MXR_MXR_RES_HEIGHT(height) | MXR_MXR_RES_WIDTH(width));
0423     else
0424         val |= ctx->scan_value;
0425 
0426     mixer_reg_writemask(ctx, MXR_CFG, val, MXR_CFG_SCAN_MASK);
0427 }
0428 
0429 static void mixer_cfg_rgb_fmt(struct mixer_context *ctx, struct drm_display_mode *mode)
0430 {
0431     enum hdmi_quantization_range range = drm_default_rgb_quant_range(mode);
0432     u32 val;
0433 
0434     if (mode->vdisplay < 720) {
0435         val = MXR_CFG_RGB601;
0436     } else {
0437         val = MXR_CFG_RGB709;
0438 
0439         /* Configure the BT.709 CSC matrix for full range RGB. */
0440         mixer_reg_write(ctx, MXR_CM_COEFF_Y,
0441             MXR_CSC_CT( 0.184,  0.614,  0.063) |
0442             MXR_CM_COEFF_RGB_FULL);
0443         mixer_reg_write(ctx, MXR_CM_COEFF_CB,
0444             MXR_CSC_CT(-0.102, -0.338,  0.440));
0445         mixer_reg_write(ctx, MXR_CM_COEFF_CR,
0446             MXR_CSC_CT( 0.440, -0.399, -0.040));
0447     }
0448 
0449     if (range == HDMI_QUANTIZATION_RANGE_FULL)
0450         val |= MXR_CFG_QUANT_RANGE_FULL;
0451     else
0452         val |= MXR_CFG_QUANT_RANGE_LIMITED;
0453 
0454     mixer_reg_writemask(ctx, MXR_CFG, val, MXR_CFG_RGB_FMT_MASK);
0455 }
0456 
0457 static void mixer_cfg_layer(struct mixer_context *ctx, unsigned int win,
0458                 unsigned int priority, bool enable)
0459 {
0460     u32 val = enable ? ~0 : 0;
0461 
0462     switch (win) {
0463     case 0:
0464         mixer_reg_writemask(ctx, MXR_CFG, val, MXR_CFG_GRP0_ENABLE);
0465         mixer_reg_writemask(ctx, MXR_LAYER_CFG,
0466                     MXR_LAYER_CFG_GRP0_VAL(priority),
0467                     MXR_LAYER_CFG_GRP0_MASK);
0468         break;
0469     case 1:
0470         mixer_reg_writemask(ctx, MXR_CFG, val, MXR_CFG_GRP1_ENABLE);
0471         mixer_reg_writemask(ctx, MXR_LAYER_CFG,
0472                     MXR_LAYER_CFG_GRP1_VAL(priority),
0473                     MXR_LAYER_CFG_GRP1_MASK);
0474 
0475         break;
0476     case VP_DEFAULT_WIN:
0477         if (test_bit(MXR_BIT_VP_ENABLED, &ctx->flags)) {
0478             vp_reg_writemask(ctx, VP_ENABLE, val, VP_ENABLE_ON);
0479             mixer_reg_writemask(ctx, MXR_CFG, val,
0480                 MXR_CFG_VP_ENABLE);
0481             mixer_reg_writemask(ctx, MXR_LAYER_CFG,
0482                         MXR_LAYER_CFG_VP_VAL(priority),
0483                         MXR_LAYER_CFG_VP_MASK);
0484         }
0485         break;
0486     }
0487 }
0488 
0489 static void mixer_run(struct mixer_context *ctx)
0490 {
0491     mixer_reg_writemask(ctx, MXR_STATUS, ~0, MXR_STATUS_REG_RUN);
0492 }
0493 
0494 static void mixer_stop(struct mixer_context *ctx)
0495 {
0496     int timeout = 20;
0497 
0498     mixer_reg_writemask(ctx, MXR_STATUS, 0, MXR_STATUS_REG_RUN);
0499 
0500     while (!(mixer_reg_read(ctx, MXR_STATUS) & MXR_STATUS_REG_IDLE) &&
0501             --timeout)
0502         usleep_range(10000, 12000);
0503 }
0504 
0505 static void mixer_commit(struct mixer_context *ctx)
0506 {
0507     struct drm_display_mode *mode = &ctx->crtc->base.state->adjusted_mode;
0508 
0509     mixer_cfg_scan(ctx, mode->hdisplay, mode->vdisplay);
0510     mixer_cfg_rgb_fmt(ctx, mode);
0511     mixer_run(ctx);
0512 }
0513 
0514 static void vp_video_buffer(struct mixer_context *ctx,
0515                 struct exynos_drm_plane *plane)
0516 {
0517     struct exynos_drm_plane_state *state =
0518                 to_exynos_plane_state(plane->base.state);
0519     struct drm_framebuffer *fb = state->base.fb;
0520     unsigned int priority = state->base.normalized_zpos + 1;
0521     unsigned long flags;
0522     dma_addr_t luma_addr[2], chroma_addr[2];
0523     bool is_tiled, is_nv21;
0524     u32 val;
0525 
0526     is_nv21 = (fb->format->format == DRM_FORMAT_NV21);
0527     is_tiled = (fb->modifier == DRM_FORMAT_MOD_SAMSUNG_64_32_TILE);
0528 
0529     luma_addr[0] = exynos_drm_fb_dma_addr(fb, 0);
0530     chroma_addr[0] = exynos_drm_fb_dma_addr(fb, 1);
0531 
0532     if (test_bit(MXR_BIT_INTERLACE, &ctx->flags)) {
0533         if (is_tiled) {
0534             luma_addr[1] = luma_addr[0] + 0x40;
0535             chroma_addr[1] = chroma_addr[0] + 0x40;
0536         } else {
0537             luma_addr[1] = luma_addr[0] + fb->pitches[0];
0538             chroma_addr[1] = chroma_addr[0] + fb->pitches[1];
0539         }
0540     } else {
0541         luma_addr[1] = 0;
0542         chroma_addr[1] = 0;
0543     }
0544 
0545     spin_lock_irqsave(&ctx->reg_slock, flags);
0546 
0547     /* interlace or progressive scan mode */
0548     val = (test_bit(MXR_BIT_INTERLACE, &ctx->flags) ? ~0 : 0);
0549     vp_reg_writemask(ctx, VP_MODE, val, VP_MODE_LINE_SKIP);
0550 
0551     /* setup format */
0552     val = (is_nv21 ? VP_MODE_NV21 : VP_MODE_NV12);
0553     val |= (is_tiled ? VP_MODE_MEM_TILED : VP_MODE_MEM_LINEAR);
0554     vp_reg_writemask(ctx, VP_MODE, val, VP_MODE_FMT_MASK);
0555 
0556     /* setting size of input image */
0557     vp_reg_write(ctx, VP_IMG_SIZE_Y, VP_IMG_HSIZE(fb->pitches[0]) |
0558         VP_IMG_VSIZE(fb->height));
0559     /* chroma plane for NV12/NV21 is half the height of the luma plane */
0560     vp_reg_write(ctx, VP_IMG_SIZE_C, VP_IMG_HSIZE(fb->pitches[1]) |
0561         VP_IMG_VSIZE(fb->height / 2));
0562 
0563     vp_reg_write(ctx, VP_SRC_WIDTH, state->src.w);
0564     vp_reg_write(ctx, VP_SRC_H_POSITION,
0565             VP_SRC_H_POSITION_VAL(state->src.x));
0566     vp_reg_write(ctx, VP_DST_WIDTH, state->crtc.w);
0567     vp_reg_write(ctx, VP_DST_H_POSITION, state->crtc.x);
0568 
0569     if (test_bit(MXR_BIT_INTERLACE, &ctx->flags)) {
0570         vp_reg_write(ctx, VP_SRC_HEIGHT, state->src.h / 2);
0571         vp_reg_write(ctx, VP_SRC_V_POSITION, state->src.y / 2);
0572         vp_reg_write(ctx, VP_DST_HEIGHT, state->crtc.h / 2);
0573         vp_reg_write(ctx, VP_DST_V_POSITION, state->crtc.y / 2);
0574     } else {
0575         vp_reg_write(ctx, VP_SRC_HEIGHT, state->src.h);
0576         vp_reg_write(ctx, VP_SRC_V_POSITION, state->src.y);
0577         vp_reg_write(ctx, VP_DST_HEIGHT, state->crtc.h);
0578         vp_reg_write(ctx, VP_DST_V_POSITION, state->crtc.y);
0579     }
0580 
0581     vp_reg_write(ctx, VP_H_RATIO, state->h_ratio);
0582     vp_reg_write(ctx, VP_V_RATIO, state->v_ratio);
0583 
0584     vp_reg_write(ctx, VP_ENDIAN_MODE, VP_ENDIAN_MODE_LITTLE);
0585 
0586     /* set buffer address to vp */
0587     vp_reg_write(ctx, VP_TOP_Y_PTR, luma_addr[0]);
0588     vp_reg_write(ctx, VP_BOT_Y_PTR, luma_addr[1]);
0589     vp_reg_write(ctx, VP_TOP_C_PTR, chroma_addr[0]);
0590     vp_reg_write(ctx, VP_BOT_C_PTR, chroma_addr[1]);
0591 
0592     mixer_cfg_layer(ctx, plane->index, priority, true);
0593     mixer_cfg_vp_blend(ctx, state->base.alpha);
0594 
0595     spin_unlock_irqrestore(&ctx->reg_slock, flags);
0596 
0597     mixer_regs_dump(ctx);
0598     vp_regs_dump(ctx);
0599 }
0600 
0601 static void mixer_graph_buffer(struct mixer_context *ctx,
0602                    struct exynos_drm_plane *plane)
0603 {
0604     struct exynos_drm_plane_state *state =
0605                 to_exynos_plane_state(plane->base.state);
0606     struct drm_framebuffer *fb = state->base.fb;
0607     unsigned int priority = state->base.normalized_zpos + 1;
0608     unsigned long flags;
0609     unsigned int win = plane->index;
0610     unsigned int x_ratio = 0, y_ratio = 0;
0611     unsigned int dst_x_offset, dst_y_offset;
0612     unsigned int pixel_alpha;
0613     dma_addr_t dma_addr;
0614     unsigned int fmt;
0615     u32 val;
0616 
0617     if (fb->format->has_alpha)
0618         pixel_alpha = state->base.pixel_blend_mode;
0619     else
0620         pixel_alpha = DRM_MODE_BLEND_PIXEL_NONE;
0621 
0622     switch (fb->format->format) {
0623     case DRM_FORMAT_XRGB4444:
0624     case DRM_FORMAT_ARGB4444:
0625         fmt = MXR_FORMAT_ARGB4444;
0626         break;
0627 
0628     case DRM_FORMAT_XRGB1555:
0629     case DRM_FORMAT_ARGB1555:
0630         fmt = MXR_FORMAT_ARGB1555;
0631         break;
0632 
0633     case DRM_FORMAT_RGB565:
0634         fmt = MXR_FORMAT_RGB565;
0635         break;
0636 
0637     case DRM_FORMAT_XRGB8888:
0638     case DRM_FORMAT_ARGB8888:
0639     default:
0640         fmt = MXR_FORMAT_ARGB8888;
0641         break;
0642     }
0643 
0644     /* ratio is already checked by common plane code */
0645     x_ratio = state->h_ratio == (1 << 15);
0646     y_ratio = state->v_ratio == (1 << 15);
0647 
0648     dst_x_offset = state->crtc.x;
0649     dst_y_offset = state->crtc.y;
0650 
0651     /* translate dma address base s.t. the source image offset is zero */
0652     dma_addr = exynos_drm_fb_dma_addr(fb, 0)
0653         + (state->src.x * fb->format->cpp[0])
0654         + (state->src.y * fb->pitches[0]);
0655 
0656     spin_lock_irqsave(&ctx->reg_slock, flags);
0657 
0658     /* setup format */
0659     mixer_reg_writemask(ctx, MXR_GRAPHIC_CFG(win),
0660         MXR_GRP_CFG_FORMAT_VAL(fmt), MXR_GRP_CFG_FORMAT_MASK);
0661 
0662     /* setup geometry */
0663     mixer_reg_write(ctx, MXR_GRAPHIC_SPAN(win),
0664             fb->pitches[0] / fb->format->cpp[0]);
0665 
0666     val  = MXR_GRP_WH_WIDTH(state->src.w);
0667     val |= MXR_GRP_WH_HEIGHT(state->src.h);
0668     val |= MXR_GRP_WH_H_SCALE(x_ratio);
0669     val |= MXR_GRP_WH_V_SCALE(y_ratio);
0670     mixer_reg_write(ctx, MXR_GRAPHIC_WH(win), val);
0671 
0672     /* setup offsets in display image */
0673     val  = MXR_GRP_DXY_DX(dst_x_offset);
0674     val |= MXR_GRP_DXY_DY(dst_y_offset);
0675     mixer_reg_write(ctx, MXR_GRAPHIC_DXY(win), val);
0676 
0677     /* set buffer address to mixer */
0678     mixer_reg_write(ctx, MXR_GRAPHIC_BASE(win), dma_addr);
0679 
0680     mixer_cfg_layer(ctx, win, priority, true);
0681     mixer_cfg_gfx_blend(ctx, win, pixel_alpha, state->base.alpha);
0682 
0683     spin_unlock_irqrestore(&ctx->reg_slock, flags);
0684 
0685     mixer_regs_dump(ctx);
0686 }
0687 
0688 static void vp_win_reset(struct mixer_context *ctx)
0689 {
0690     unsigned int tries = 100;
0691 
0692     vp_reg_write(ctx, VP_SRESET, VP_SRESET_PROCESSING);
0693     while (--tries) {
0694         /* waiting until VP_SRESET_PROCESSING is 0 */
0695         if (~vp_reg_read(ctx, VP_SRESET) & VP_SRESET_PROCESSING)
0696             break;
0697         mdelay(10);
0698     }
0699     WARN(tries == 0, "failed to reset Video Processor\n");
0700 }
0701 
0702 static void mixer_win_reset(struct mixer_context *ctx)
0703 {
0704     unsigned long flags;
0705 
0706     spin_lock_irqsave(&ctx->reg_slock, flags);
0707 
0708     mixer_reg_writemask(ctx, MXR_CFG, MXR_CFG_DST_HDMI, MXR_CFG_DST_MASK);
0709 
0710     /* set output in RGB888 mode */
0711     mixer_reg_writemask(ctx, MXR_CFG, MXR_CFG_OUT_RGB888, MXR_CFG_OUT_MASK);
0712 
0713     /* 16 beat burst in DMA */
0714     mixer_reg_writemask(ctx, MXR_STATUS, MXR_STATUS_16_BURST,
0715         MXR_STATUS_BURST_MASK);
0716 
0717     /* reset default layer priority */
0718     mixer_reg_write(ctx, MXR_LAYER_CFG, 0);
0719 
0720     /* set all background colors to RGB (0,0,0) */
0721     mixer_reg_write(ctx, MXR_BG_COLOR0, MXR_YCBCR_VAL(0, 128, 128));
0722     mixer_reg_write(ctx, MXR_BG_COLOR1, MXR_YCBCR_VAL(0, 128, 128));
0723     mixer_reg_write(ctx, MXR_BG_COLOR2, MXR_YCBCR_VAL(0, 128, 128));
0724 
0725     if (test_bit(MXR_BIT_VP_ENABLED, &ctx->flags)) {
0726         /* configuration of Video Processor Registers */
0727         vp_win_reset(ctx);
0728         vp_default_filter(ctx);
0729     }
0730 
0731     /* disable all layers */
0732     mixer_reg_writemask(ctx, MXR_CFG, 0, MXR_CFG_GRP0_ENABLE);
0733     mixer_reg_writemask(ctx, MXR_CFG, 0, MXR_CFG_GRP1_ENABLE);
0734     if (test_bit(MXR_BIT_VP_ENABLED, &ctx->flags))
0735         mixer_reg_writemask(ctx, MXR_CFG, 0, MXR_CFG_VP_ENABLE);
0736 
0737     /* set all source image offsets to zero */
0738     mixer_reg_write(ctx, MXR_GRAPHIC_SXY(0), 0);
0739     mixer_reg_write(ctx, MXR_GRAPHIC_SXY(1), 0);
0740 
0741     spin_unlock_irqrestore(&ctx->reg_slock, flags);
0742 }
0743 
0744 static irqreturn_t mixer_irq_handler(int irq, void *arg)
0745 {
0746     struct mixer_context *ctx = arg;
0747     u32 val;
0748 
0749     spin_lock(&ctx->reg_slock);
0750 
0751     /* read interrupt status for handling and clearing flags for VSYNC */
0752     val = mixer_reg_read(ctx, MXR_INT_STATUS);
0753 
0754     /* handling VSYNC */
0755     if (val & MXR_INT_STATUS_VSYNC) {
0756         /* vsync interrupt use different bit for read and clear */
0757         val |= MXR_INT_CLEAR_VSYNC;
0758         val &= ~MXR_INT_STATUS_VSYNC;
0759 
0760         /* interlace scan need to check shadow register */
0761         if (test_bit(MXR_BIT_INTERLACE, &ctx->flags)
0762             && !mixer_is_synced(ctx))
0763             goto out;
0764 
0765         drm_crtc_handle_vblank(&ctx->crtc->base);
0766     }
0767 
0768 out:
0769     /* clear interrupts */
0770     mixer_reg_write(ctx, MXR_INT_STATUS, val);
0771 
0772     spin_unlock(&ctx->reg_slock);
0773 
0774     return IRQ_HANDLED;
0775 }
0776 
0777 static int mixer_resources_init(struct mixer_context *mixer_ctx)
0778 {
0779     struct device *dev = &mixer_ctx->pdev->dev;
0780     struct resource *res;
0781     int ret;
0782 
0783     spin_lock_init(&mixer_ctx->reg_slock);
0784 
0785     mixer_ctx->mixer = devm_clk_get(dev, "mixer");
0786     if (IS_ERR(mixer_ctx->mixer)) {
0787         dev_err(dev, "failed to get clock 'mixer'\n");
0788         return -ENODEV;
0789     }
0790 
0791     mixer_ctx->hdmi = devm_clk_get(dev, "hdmi");
0792     if (IS_ERR(mixer_ctx->hdmi)) {
0793         dev_err(dev, "failed to get clock 'hdmi'\n");
0794         return PTR_ERR(mixer_ctx->hdmi);
0795     }
0796 
0797     mixer_ctx->sclk_hdmi = devm_clk_get(dev, "sclk_hdmi");
0798     if (IS_ERR(mixer_ctx->sclk_hdmi)) {
0799         dev_err(dev, "failed to get clock 'sclk_hdmi'\n");
0800         return -ENODEV;
0801     }
0802     res = platform_get_resource(mixer_ctx->pdev, IORESOURCE_MEM, 0);
0803     if (res == NULL) {
0804         dev_err(dev, "get memory resource failed.\n");
0805         return -ENXIO;
0806     }
0807 
0808     mixer_ctx->mixer_regs = devm_ioremap(dev, res->start,
0809                             resource_size(res));
0810     if (mixer_ctx->mixer_regs == NULL) {
0811         dev_err(dev, "register mapping failed.\n");
0812         return -ENXIO;
0813     }
0814 
0815     ret = platform_get_irq(mixer_ctx->pdev, 0);
0816     if (ret < 0)
0817         return ret;
0818     mixer_ctx->irq = ret;
0819 
0820     ret = devm_request_irq(dev, mixer_ctx->irq, mixer_irq_handler,
0821                    0, "drm_mixer", mixer_ctx);
0822     if (ret) {
0823         dev_err(dev, "request interrupt failed.\n");
0824         return ret;
0825     }
0826 
0827     return 0;
0828 }
0829 
0830 static int vp_resources_init(struct mixer_context *mixer_ctx)
0831 {
0832     struct device *dev = &mixer_ctx->pdev->dev;
0833     struct resource *res;
0834 
0835     mixer_ctx->vp = devm_clk_get(dev, "vp");
0836     if (IS_ERR(mixer_ctx->vp)) {
0837         dev_err(dev, "failed to get clock 'vp'\n");
0838         return -ENODEV;
0839     }
0840 
0841     if (test_bit(MXR_BIT_HAS_SCLK, &mixer_ctx->flags)) {
0842         mixer_ctx->sclk_mixer = devm_clk_get(dev, "sclk_mixer");
0843         if (IS_ERR(mixer_ctx->sclk_mixer)) {
0844             dev_err(dev, "failed to get clock 'sclk_mixer'\n");
0845             return -ENODEV;
0846         }
0847         mixer_ctx->mout_mixer = devm_clk_get(dev, "mout_mixer");
0848         if (IS_ERR(mixer_ctx->mout_mixer)) {
0849             dev_err(dev, "failed to get clock 'mout_mixer'\n");
0850             return -ENODEV;
0851         }
0852 
0853         if (mixer_ctx->sclk_hdmi && mixer_ctx->mout_mixer)
0854             clk_set_parent(mixer_ctx->mout_mixer,
0855                        mixer_ctx->sclk_hdmi);
0856     }
0857 
0858     res = platform_get_resource(mixer_ctx->pdev, IORESOURCE_MEM, 1);
0859     if (res == NULL) {
0860         dev_err(dev, "get memory resource failed.\n");
0861         return -ENXIO;
0862     }
0863 
0864     mixer_ctx->vp_regs = devm_ioremap(dev, res->start,
0865                             resource_size(res));
0866     if (mixer_ctx->vp_regs == NULL) {
0867         dev_err(dev, "register mapping failed.\n");
0868         return -ENXIO;
0869     }
0870 
0871     return 0;
0872 }
0873 
0874 static int mixer_initialize(struct mixer_context *mixer_ctx,
0875             struct drm_device *drm_dev)
0876 {
0877     int ret;
0878 
0879     mixer_ctx->drm_dev = drm_dev;
0880 
0881     /* acquire resources: regs, irqs, clocks */
0882     ret = mixer_resources_init(mixer_ctx);
0883     if (ret) {
0884         DRM_DEV_ERROR(mixer_ctx->dev,
0885                   "mixer_resources_init failed ret=%d\n", ret);
0886         return ret;
0887     }
0888 
0889     if (test_bit(MXR_BIT_VP_ENABLED, &mixer_ctx->flags)) {
0890         /* acquire vp resources: regs, irqs, clocks */
0891         ret = vp_resources_init(mixer_ctx);
0892         if (ret) {
0893             DRM_DEV_ERROR(mixer_ctx->dev,
0894                       "vp_resources_init failed ret=%d\n", ret);
0895             return ret;
0896         }
0897     }
0898 
0899     return exynos_drm_register_dma(drm_dev, mixer_ctx->dev,
0900                        &mixer_ctx->dma_priv);
0901 }
0902 
0903 static void mixer_ctx_remove(struct mixer_context *mixer_ctx)
0904 {
0905     exynos_drm_unregister_dma(mixer_ctx->drm_dev, mixer_ctx->dev,
0906                   &mixer_ctx->dma_priv);
0907 }
0908 
0909 static int mixer_enable_vblank(struct exynos_drm_crtc *crtc)
0910 {
0911     struct mixer_context *mixer_ctx = crtc->ctx;
0912 
0913     __set_bit(MXR_BIT_VSYNC, &mixer_ctx->flags);
0914     if (!test_bit(MXR_BIT_POWERED, &mixer_ctx->flags))
0915         return 0;
0916 
0917     /* enable vsync interrupt */
0918     mixer_reg_writemask(mixer_ctx, MXR_INT_STATUS, ~0, MXR_INT_CLEAR_VSYNC);
0919     mixer_reg_writemask(mixer_ctx, MXR_INT_EN, ~0, MXR_INT_EN_VSYNC);
0920 
0921     return 0;
0922 }
0923 
0924 static void mixer_disable_vblank(struct exynos_drm_crtc *crtc)
0925 {
0926     struct mixer_context *mixer_ctx = crtc->ctx;
0927 
0928     __clear_bit(MXR_BIT_VSYNC, &mixer_ctx->flags);
0929 
0930     if (!test_bit(MXR_BIT_POWERED, &mixer_ctx->flags))
0931         return;
0932 
0933     /* disable vsync interrupt */
0934     mixer_reg_writemask(mixer_ctx, MXR_INT_STATUS, ~0, MXR_INT_CLEAR_VSYNC);
0935     mixer_reg_writemask(mixer_ctx, MXR_INT_EN, 0, MXR_INT_EN_VSYNC);
0936 }
0937 
0938 static void mixer_atomic_begin(struct exynos_drm_crtc *crtc)
0939 {
0940     struct mixer_context *ctx = crtc->ctx;
0941 
0942     if (!test_bit(MXR_BIT_POWERED, &ctx->flags))
0943         return;
0944 
0945     if (mixer_wait_for_sync(ctx))
0946         dev_err(ctx->dev, "timeout waiting for VSYNC\n");
0947     mixer_disable_sync(ctx);
0948 }
0949 
0950 static void mixer_update_plane(struct exynos_drm_crtc *crtc,
0951                    struct exynos_drm_plane *plane)
0952 {
0953     struct mixer_context *mixer_ctx = crtc->ctx;
0954 
0955     DRM_DEV_DEBUG_KMS(mixer_ctx->dev, "win: %d\n", plane->index);
0956 
0957     if (!test_bit(MXR_BIT_POWERED, &mixer_ctx->flags))
0958         return;
0959 
0960     if (plane->index == VP_DEFAULT_WIN)
0961         vp_video_buffer(mixer_ctx, plane);
0962     else
0963         mixer_graph_buffer(mixer_ctx, plane);
0964 }
0965 
0966 static void mixer_disable_plane(struct exynos_drm_crtc *crtc,
0967                 struct exynos_drm_plane *plane)
0968 {
0969     struct mixer_context *mixer_ctx = crtc->ctx;
0970     unsigned long flags;
0971 
0972     DRM_DEV_DEBUG_KMS(mixer_ctx->dev, "win: %d\n", plane->index);
0973 
0974     if (!test_bit(MXR_BIT_POWERED, &mixer_ctx->flags))
0975         return;
0976 
0977     spin_lock_irqsave(&mixer_ctx->reg_slock, flags);
0978     mixer_cfg_layer(mixer_ctx, plane->index, 0, false);
0979     spin_unlock_irqrestore(&mixer_ctx->reg_slock, flags);
0980 }
0981 
0982 static void mixer_atomic_flush(struct exynos_drm_crtc *crtc)
0983 {
0984     struct mixer_context *mixer_ctx = crtc->ctx;
0985 
0986     if (!test_bit(MXR_BIT_POWERED, &mixer_ctx->flags))
0987         return;
0988 
0989     mixer_enable_sync(mixer_ctx);
0990     exynos_crtc_handle_event(crtc);
0991 }
0992 
0993 static void mixer_atomic_enable(struct exynos_drm_crtc *crtc)
0994 {
0995     struct mixer_context *ctx = crtc->ctx;
0996     int ret;
0997 
0998     if (test_bit(MXR_BIT_POWERED, &ctx->flags))
0999         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 int 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 };