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