Linux Audio

Check our new training course

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