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