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