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