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