Linux Audio

Check our new training course

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