cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

exynos_mixer.c (34773B)


      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	ret = platform_get_irq(mixer_ctx->pdev, 0);
    813	if (ret < 0)
    814		return ret;
    815	mixer_ctx->irq = ret;
    816
    817	ret = devm_request_irq(dev, mixer_ctx->irq, mixer_irq_handler,
    818			       0, "drm_mixer", mixer_ctx);
    819	if (ret) {
    820		dev_err(dev, "request interrupt failed.\n");
    821		return ret;
    822	}
    823
    824	return 0;
    825}
    826
    827static int vp_resources_init(struct mixer_context *mixer_ctx)
    828{
    829	struct device *dev = &mixer_ctx->pdev->dev;
    830	struct resource *res;
    831
    832	mixer_ctx->vp = devm_clk_get(dev, "vp");
    833	if (IS_ERR(mixer_ctx->vp)) {
    834		dev_err(dev, "failed to get clock 'vp'\n");
    835		return -ENODEV;
    836	}
    837
    838	if (test_bit(MXR_BIT_HAS_SCLK, &mixer_ctx->flags)) {
    839		mixer_ctx->sclk_mixer = devm_clk_get(dev, "sclk_mixer");
    840		if (IS_ERR(mixer_ctx->sclk_mixer)) {
    841			dev_err(dev, "failed to get clock 'sclk_mixer'\n");
    842			return -ENODEV;
    843		}
    844		mixer_ctx->mout_mixer = devm_clk_get(dev, "mout_mixer");
    845		if (IS_ERR(mixer_ctx->mout_mixer)) {
    846			dev_err(dev, "failed to get clock 'mout_mixer'\n");
    847			return -ENODEV;
    848		}
    849
    850		if (mixer_ctx->sclk_hdmi && mixer_ctx->mout_mixer)
    851			clk_set_parent(mixer_ctx->mout_mixer,
    852				       mixer_ctx->sclk_hdmi);
    853	}
    854
    855	res = platform_get_resource(mixer_ctx->pdev, IORESOURCE_MEM, 1);
    856	if (res == NULL) {
    857		dev_err(dev, "get memory resource failed.\n");
    858		return -ENXIO;
    859	}
    860
    861	mixer_ctx->vp_regs = devm_ioremap(dev, res->start,
    862							resource_size(res));
    863	if (mixer_ctx->vp_regs == NULL) {
    864		dev_err(dev, "register mapping failed.\n");
    865		return -ENXIO;
    866	}
    867
    868	return 0;
    869}
    870
    871static int mixer_initialize(struct mixer_context *mixer_ctx,
    872			struct drm_device *drm_dev)
    873{
    874	int ret;
    875
    876	mixer_ctx->drm_dev = drm_dev;
    877
    878	/* acquire resources: regs, irqs, clocks */
    879	ret = mixer_resources_init(mixer_ctx);
    880	if (ret) {
    881		DRM_DEV_ERROR(mixer_ctx->dev,
    882			      "mixer_resources_init failed ret=%d\n", ret);
    883		return ret;
    884	}
    885
    886	if (test_bit(MXR_BIT_VP_ENABLED, &mixer_ctx->flags)) {
    887		/* acquire vp resources: regs, irqs, clocks */
    888		ret = vp_resources_init(mixer_ctx);
    889		if (ret) {
    890			DRM_DEV_ERROR(mixer_ctx->dev,
    891				      "vp_resources_init failed ret=%d\n", ret);
    892			return ret;
    893		}
    894	}
    895
    896	return exynos_drm_register_dma(drm_dev, mixer_ctx->dev,
    897				       &mixer_ctx->dma_priv);
    898}
    899
    900static void mixer_ctx_remove(struct mixer_context *mixer_ctx)
    901{
    902	exynos_drm_unregister_dma(mixer_ctx->drm_dev, mixer_ctx->dev,
    903				  &mixer_ctx->dma_priv);
    904}
    905
    906static int mixer_enable_vblank(struct exynos_drm_crtc *crtc)
    907{
    908	struct mixer_context *mixer_ctx = crtc->ctx;
    909
    910	__set_bit(MXR_BIT_VSYNC, &mixer_ctx->flags);
    911	if (!test_bit(MXR_BIT_POWERED, &mixer_ctx->flags))
    912		return 0;
    913
    914	/* enable vsync interrupt */
    915	mixer_reg_writemask(mixer_ctx, MXR_INT_STATUS, ~0, MXR_INT_CLEAR_VSYNC);
    916	mixer_reg_writemask(mixer_ctx, MXR_INT_EN, ~0, MXR_INT_EN_VSYNC);
    917
    918	return 0;
    919}
    920
    921static void mixer_disable_vblank(struct exynos_drm_crtc *crtc)
    922{
    923	struct mixer_context *mixer_ctx = crtc->ctx;
    924
    925	__clear_bit(MXR_BIT_VSYNC, &mixer_ctx->flags);
    926
    927	if (!test_bit(MXR_BIT_POWERED, &mixer_ctx->flags))
    928		return;
    929
    930	/* disable vsync interrupt */
    931	mixer_reg_writemask(mixer_ctx, MXR_INT_STATUS, ~0, MXR_INT_CLEAR_VSYNC);
    932	mixer_reg_writemask(mixer_ctx, MXR_INT_EN, 0, MXR_INT_EN_VSYNC);
    933}
    934
    935static void mixer_atomic_begin(struct exynos_drm_crtc *crtc)
    936{
    937	struct mixer_context *ctx = crtc->ctx;
    938
    939	if (!test_bit(MXR_BIT_POWERED, &ctx->flags))
    940		return;
    941
    942	if (mixer_wait_for_sync(ctx))
    943		dev_err(ctx->dev, "timeout waiting for VSYNC\n");
    944	mixer_disable_sync(ctx);
    945}
    946
    947static void mixer_update_plane(struct exynos_drm_crtc *crtc,
    948			       struct exynos_drm_plane *plane)
    949{
    950	struct mixer_context *mixer_ctx = crtc->ctx;
    951
    952	DRM_DEV_DEBUG_KMS(mixer_ctx->dev, "win: %d\n", plane->index);
    953
    954	if (!test_bit(MXR_BIT_POWERED, &mixer_ctx->flags))
    955		return;
    956
    957	if (plane->index == VP_DEFAULT_WIN)
    958		vp_video_buffer(mixer_ctx, plane);
    959	else
    960		mixer_graph_buffer(mixer_ctx, plane);
    961}
    962
    963static void mixer_disable_plane(struct exynos_drm_crtc *crtc,
    964				struct exynos_drm_plane *plane)
    965{
    966	struct mixer_context *mixer_ctx = crtc->ctx;
    967	unsigned long flags;
    968
    969	DRM_DEV_DEBUG_KMS(mixer_ctx->dev, "win: %d\n", plane->index);
    970
    971	if (!test_bit(MXR_BIT_POWERED, &mixer_ctx->flags))
    972		return;
    973
    974	spin_lock_irqsave(&mixer_ctx->reg_slock, flags);
    975	mixer_cfg_layer(mixer_ctx, plane->index, 0, false);
    976	spin_unlock_irqrestore(&mixer_ctx->reg_slock, flags);
    977}
    978
    979static void mixer_atomic_flush(struct exynos_drm_crtc *crtc)
    980{
    981	struct mixer_context *mixer_ctx = crtc->ctx;
    982
    983	if (!test_bit(MXR_BIT_POWERED, &mixer_ctx->flags))
    984		return;
    985
    986	mixer_enable_sync(mixer_ctx);
    987	exynos_crtc_handle_event(crtc);
    988}
    989
    990static void mixer_atomic_enable(struct exynos_drm_crtc *crtc)
    991{
    992	struct mixer_context *ctx = crtc->ctx;
    993	int ret;
    994
    995	if (test_bit(MXR_BIT_POWERED, &ctx->flags))
    996		return;
    997
    998	ret = pm_runtime_resume_and_get(ctx->dev);
    999	if (ret < 0) {
   1000		dev_err(ctx->dev, "failed to enable MIXER device.\n");
   1001		return;
   1002	}
   1003
   1004	exynos_drm_pipe_clk_enable(crtc, true);
   1005
   1006	mixer_disable_sync(ctx);
   1007
   1008	mixer_reg_writemask(ctx, MXR_STATUS, ~0, MXR_STATUS_SOFT_RESET);
   1009
   1010	if (test_bit(MXR_BIT_VSYNC, &ctx->flags)) {
   1011		mixer_reg_writemask(ctx, MXR_INT_STATUS, ~0,
   1012					MXR_INT_CLEAR_VSYNC);
   1013		mixer_reg_writemask(ctx, MXR_INT_EN, ~0, MXR_INT_EN_VSYNC);
   1014	}
   1015	mixer_win_reset(ctx);
   1016
   1017	mixer_commit(ctx);
   1018
   1019	mixer_enable_sync(ctx);
   1020
   1021	set_bit(MXR_BIT_POWERED, &ctx->flags);
   1022}
   1023
   1024static void mixer_atomic_disable(struct exynos_drm_crtc *crtc)
   1025{
   1026	struct mixer_context *ctx = crtc->ctx;
   1027	int i;
   1028
   1029	if (!test_bit(MXR_BIT_POWERED, &ctx->flags))
   1030		return;
   1031
   1032	mixer_stop(ctx);
   1033	mixer_regs_dump(ctx);
   1034
   1035	for (i = 0; i < MIXER_WIN_NR; i++)
   1036		mixer_disable_plane(crtc, &ctx->planes[i]);
   1037
   1038	exynos_drm_pipe_clk_enable(crtc, false);
   1039
   1040	pm_runtime_put(ctx->dev);
   1041
   1042	clear_bit(MXR_BIT_POWERED, &ctx->flags);
   1043}
   1044
   1045static int mixer_mode_valid(struct exynos_drm_crtc *crtc,
   1046		const struct drm_display_mode *mode)
   1047{
   1048	struct mixer_context *ctx = crtc->ctx;
   1049	u32 w = mode->hdisplay, h = mode->vdisplay;
   1050
   1051	DRM_DEV_DEBUG_KMS(ctx->dev, "xres=%d, yres=%d, refresh=%d, intl=%d\n",
   1052			  w, h, drm_mode_vrefresh(mode),
   1053			  !!(mode->flags & DRM_MODE_FLAG_INTERLACE));
   1054
   1055	if (ctx->mxr_ver == MXR_VER_128_0_0_184)
   1056		return MODE_OK;
   1057
   1058	if ((w >= 464 && w <= 720 && h >= 261 && h <= 576) ||
   1059	    (w >= 1024 && w <= 1280 && h >= 576 && h <= 720) ||
   1060	    (w >= 1664 && w <= 1920 && h >= 936 && h <= 1080))
   1061		return MODE_OK;
   1062
   1063	if ((w == 1024 && h == 768) ||
   1064	    (w == 1366 && h == 768) ||
   1065	    (w == 1280 && h == 1024))
   1066		return MODE_OK;
   1067
   1068	return MODE_BAD;
   1069}
   1070
   1071static bool mixer_mode_fixup(struct exynos_drm_crtc *crtc,
   1072		   const struct drm_display_mode *mode,
   1073		   struct drm_display_mode *adjusted_mode)
   1074{
   1075	struct mixer_context *ctx = crtc->ctx;
   1076	int width = mode->hdisplay, height = mode->vdisplay, i;
   1077
   1078	static const struct {
   1079		int hdisplay, vdisplay, htotal, vtotal, scan_val;
   1080	} modes[] = {
   1081		{ 720, 480, 858, 525, MXR_CFG_SCAN_NTSC | MXR_CFG_SCAN_SD },
   1082		{ 720, 576, 864, 625, MXR_CFG_SCAN_PAL | MXR_CFG_SCAN_SD },
   1083		{ 1280, 720, 1650, 750, MXR_CFG_SCAN_HD_720 | MXR_CFG_SCAN_HD },
   1084		{ 1920, 1080, 2200, 1125, MXR_CFG_SCAN_HD_1080 |
   1085						MXR_CFG_SCAN_HD }
   1086	};
   1087
   1088	if (mode->flags & DRM_MODE_FLAG_INTERLACE)
   1089		__set_bit(MXR_BIT_INTERLACE, &ctx->flags);
   1090	else
   1091		__clear_bit(MXR_BIT_INTERLACE, &ctx->flags);
   1092
   1093	if (ctx->mxr_ver == MXR_VER_128_0_0_184)
   1094		return true;
   1095
   1096	for (i = 0; i < ARRAY_SIZE(modes); ++i)
   1097		if (width <= modes[i].hdisplay && height <= modes[i].vdisplay) {
   1098			ctx->scan_value = modes[i].scan_val;
   1099			if (width < modes[i].hdisplay ||
   1100			    height < modes[i].vdisplay) {
   1101				adjusted_mode->hdisplay = modes[i].hdisplay;
   1102				adjusted_mode->hsync_start = modes[i].hdisplay;
   1103				adjusted_mode->hsync_end = modes[i].htotal;
   1104				adjusted_mode->htotal = modes[i].htotal;
   1105				adjusted_mode->vdisplay = modes[i].vdisplay;
   1106				adjusted_mode->vsync_start = modes[i].vdisplay;
   1107				adjusted_mode->vsync_end = modes[i].vtotal;
   1108				adjusted_mode->vtotal = modes[i].vtotal;
   1109			}
   1110
   1111			return true;
   1112		}
   1113
   1114	return false;
   1115}
   1116
   1117static const struct exynos_drm_crtc_ops mixer_crtc_ops = {
   1118	.atomic_enable		= mixer_atomic_enable,
   1119	.atomic_disable		= mixer_atomic_disable,
   1120	.enable_vblank		= mixer_enable_vblank,
   1121	.disable_vblank		= mixer_disable_vblank,
   1122	.atomic_begin		= mixer_atomic_begin,
   1123	.update_plane		= mixer_update_plane,
   1124	.disable_plane		= mixer_disable_plane,
   1125	.atomic_flush		= mixer_atomic_flush,
   1126	.mode_valid		= mixer_mode_valid,
   1127	.mode_fixup		= mixer_mode_fixup,
   1128};
   1129
   1130static const struct mixer_drv_data exynos5420_mxr_drv_data = {
   1131	.version = MXR_VER_128_0_0_184,
   1132	.is_vp_enabled = 0,
   1133};
   1134
   1135static const struct mixer_drv_data exynos5250_mxr_drv_data = {
   1136	.version = MXR_VER_16_0_33_0,
   1137	.is_vp_enabled = 0,
   1138};
   1139
   1140static const struct mixer_drv_data exynos4212_mxr_drv_data = {
   1141	.version = MXR_VER_0_0_0_16,
   1142	.is_vp_enabled = 1,
   1143};
   1144
   1145static const struct mixer_drv_data exynos4210_mxr_drv_data = {
   1146	.version = MXR_VER_0_0_0_16,
   1147	.is_vp_enabled = 1,
   1148	.has_sclk = 1,
   1149};
   1150
   1151static const struct of_device_id mixer_match_types[] = {
   1152	{
   1153		.compatible = "samsung,exynos4210-mixer",
   1154		.data	= &exynos4210_mxr_drv_data,
   1155	}, {
   1156		.compatible = "samsung,exynos4212-mixer",
   1157		.data	= &exynos4212_mxr_drv_data,
   1158	}, {
   1159		.compatible = "samsung,exynos5-mixer",
   1160		.data	= &exynos5250_mxr_drv_data,
   1161	}, {
   1162		.compatible = "samsung,exynos5250-mixer",
   1163		.data	= &exynos5250_mxr_drv_data,
   1164	}, {
   1165		.compatible = "samsung,exynos5420-mixer",
   1166		.data	= &exynos5420_mxr_drv_data,
   1167	}, {
   1168		/* end node */
   1169	}
   1170};
   1171MODULE_DEVICE_TABLE(of, mixer_match_types);
   1172
   1173static int mixer_bind(struct device *dev, struct device *manager, void *data)
   1174{
   1175	struct mixer_context *ctx = dev_get_drvdata(dev);
   1176	struct drm_device *drm_dev = data;
   1177	struct exynos_drm_plane *exynos_plane;
   1178	unsigned int i;
   1179	int ret;
   1180
   1181	ret = mixer_initialize(ctx, drm_dev);
   1182	if (ret)
   1183		return ret;
   1184
   1185	for (i = 0; i < MIXER_WIN_NR; i++) {
   1186		if (i == VP_DEFAULT_WIN && !test_bit(MXR_BIT_VP_ENABLED,
   1187						     &ctx->flags))
   1188			continue;
   1189
   1190		ret = exynos_plane_init(drm_dev, &ctx->planes[i], i,
   1191					&plane_configs[i]);
   1192		if (ret)
   1193			return ret;
   1194	}
   1195
   1196	exynos_plane = &ctx->planes[DEFAULT_WIN];
   1197	ctx->crtc = exynos_drm_crtc_create(drm_dev, &exynos_plane->base,
   1198			EXYNOS_DISPLAY_TYPE_HDMI, &mixer_crtc_ops, ctx);
   1199	if (IS_ERR(ctx->crtc)) {
   1200		mixer_ctx_remove(ctx);
   1201		ret = PTR_ERR(ctx->crtc);
   1202		goto free_ctx;
   1203	}
   1204
   1205	return 0;
   1206
   1207free_ctx:
   1208	devm_kfree(dev, ctx);
   1209	return ret;
   1210}
   1211
   1212static void mixer_unbind(struct device *dev, struct device *master, void *data)
   1213{
   1214	struct mixer_context *ctx = dev_get_drvdata(dev);
   1215
   1216	mixer_ctx_remove(ctx);
   1217}
   1218
   1219static const struct component_ops mixer_component_ops = {
   1220	.bind	= mixer_bind,
   1221	.unbind	= mixer_unbind,
   1222};
   1223
   1224static int mixer_probe(struct platform_device *pdev)
   1225{
   1226	struct device *dev = &pdev->dev;
   1227	const struct mixer_drv_data *drv;
   1228	struct mixer_context *ctx;
   1229	int ret;
   1230
   1231	ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
   1232	if (!ctx) {
   1233		DRM_DEV_ERROR(dev, "failed to alloc mixer context.\n");
   1234		return -ENOMEM;
   1235	}
   1236
   1237	drv = of_device_get_match_data(dev);
   1238
   1239	ctx->pdev = pdev;
   1240	ctx->dev = dev;
   1241	ctx->mxr_ver = drv->version;
   1242
   1243	if (drv->is_vp_enabled)
   1244		__set_bit(MXR_BIT_VP_ENABLED, &ctx->flags);
   1245	if (drv->has_sclk)
   1246		__set_bit(MXR_BIT_HAS_SCLK, &ctx->flags);
   1247
   1248	platform_set_drvdata(pdev, ctx);
   1249
   1250	pm_runtime_enable(dev);
   1251
   1252	ret = component_add(&pdev->dev, &mixer_component_ops);
   1253	if (ret)
   1254		pm_runtime_disable(dev);
   1255
   1256	return ret;
   1257}
   1258
   1259static int mixer_remove(struct platform_device *pdev)
   1260{
   1261	pm_runtime_disable(&pdev->dev);
   1262
   1263	component_del(&pdev->dev, &mixer_component_ops);
   1264
   1265	return 0;
   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 = mixer_remove,
   1340};