• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* drivers/gpu/drm/exynos5433_drm_decon.c
2  *
3  * Copyright (C) 2015 Samsung Electronics Co.Ltd
4  * Authors:
5  *	Joonyoung Shim <jy0922.shim@samsung.com>
6  *	Hyungwon Hwang <human.hwang@samsung.com>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License version 2 as
10  * published by the Free Software Foundationr
11  */
12 
13 #include <linux/platform_device.h>
14 #include <linux/clk.h>
15 #include <linux/component.h>
16 #include <linux/of_device.h>
17 #include <linux/of_gpio.h>
18 #include <linux/pm_runtime.h>
19 
20 #include <video/exynos5433_decon.h>
21 
22 #include "exynos_drm_drv.h"
23 #include "exynos_drm_crtc.h"
24 #include "exynos_drm_plane.h"
25 #include "exynos_drm_iommu.h"
26 
27 #define WINDOWS_NR	3
28 #define CURSOR_WIN	2
29 #define MIN_FB_WIDTH_FOR_16WORD_BURST	128
30 
31 static const char * const decon_clks_name[] = {
32 	"pclk",
33 	"aclk_decon",
34 	"aclk_smmu_decon0x",
35 	"aclk_xiu_decon0x",
36 	"pclk_smmu_decon0x",
37 	"sclk_decon_vclk",
38 	"sclk_decon_eclk",
39 };
40 
41 enum decon_iftype {
42 	IFTYPE_RGB,
43 	IFTYPE_I80,
44 	IFTYPE_HDMI
45 };
46 
47 enum decon_flag_bits {
48 	BIT_CLKS_ENABLED,
49 	BIT_IRQS_ENABLED,
50 	BIT_WIN_UPDATED,
51 	BIT_SUSPENDED
52 };
53 
54 struct decon_context {
55 	struct device			*dev;
56 	struct drm_device		*drm_dev;
57 	struct exynos_drm_crtc		*crtc;
58 	struct exynos_drm_plane		planes[WINDOWS_NR];
59 	void __iomem			*addr;
60 	struct clk			*clks[ARRAY_SIZE(decon_clks_name)];
61 	int				pipe;
62 	unsigned long			flags;
63 	enum decon_iftype		out_type;
64 	int				first_win;
65 };
66 
67 static const uint32_t decon_formats[] = {
68 	DRM_FORMAT_XRGB1555,
69 	DRM_FORMAT_RGB565,
70 	DRM_FORMAT_XRGB8888,
71 	DRM_FORMAT_ARGB8888,
72 };
73 
decon_set_bits(struct decon_context * ctx,u32 reg,u32 mask,u32 val)74 static inline void decon_set_bits(struct decon_context *ctx, u32 reg, u32 mask,
75 				  u32 val)
76 {
77 	val = (val & mask) | (readl(ctx->addr + reg) & ~mask);
78 	writel(val, ctx->addr + reg);
79 }
80 
decon_enable_vblank(struct exynos_drm_crtc * crtc)81 static int decon_enable_vblank(struct exynos_drm_crtc *crtc)
82 {
83 	struct decon_context *ctx = crtc->ctx;
84 	u32 val;
85 
86 	if (test_bit(BIT_SUSPENDED, &ctx->flags))
87 		return -EPERM;
88 
89 	if (test_and_set_bit(BIT_IRQS_ENABLED, &ctx->flags)) {
90 		val = VIDINTCON0_INTEN;
91 		if (ctx->out_type == IFTYPE_I80)
92 			val |= VIDINTCON0_FRAMEDONE;
93 		else
94 			val |= VIDINTCON0_INTFRMEN;
95 
96 		writel(val, ctx->addr + DECON_VIDINTCON0);
97 	}
98 
99 	return 0;
100 }
101 
decon_disable_vblank(struct exynos_drm_crtc * crtc)102 static void decon_disable_vblank(struct exynos_drm_crtc *crtc)
103 {
104 	struct decon_context *ctx = crtc->ctx;
105 
106 	if (test_bit(BIT_SUSPENDED, &ctx->flags))
107 		return;
108 
109 	if (test_and_clear_bit(BIT_IRQS_ENABLED, &ctx->flags))
110 		writel(0, ctx->addr + DECON_VIDINTCON0);
111 }
112 
decon_setup_trigger(struct decon_context * ctx)113 static void decon_setup_trigger(struct decon_context *ctx)
114 {
115 	u32 val = (ctx->out_type != IFTYPE_HDMI)
116 		? TRIGCON_TRIGEN_PER_F | TRIGCON_TRIGEN_F |
117 		  TRIGCON_TE_AUTO_MASK | TRIGCON_SWTRIGEN
118 		: TRIGCON_TRIGEN_PER_F | TRIGCON_TRIGEN_F |
119 		  TRIGCON_HWTRIGMASK_I80_RGB | TRIGCON_HWTRIGEN_I80_RGB;
120 	writel(val, ctx->addr + DECON_TRIGCON);
121 }
122 
decon_commit(struct exynos_drm_crtc * crtc)123 static void decon_commit(struct exynos_drm_crtc *crtc)
124 {
125 	struct decon_context *ctx = crtc->ctx;
126 	struct drm_display_mode *m = &crtc->base.mode;
127 	u32 val;
128 
129 	if (test_bit(BIT_SUSPENDED, &ctx->flags))
130 		return;
131 
132 	if (ctx->out_type == IFTYPE_HDMI) {
133 		m->crtc_hsync_start = m->crtc_hdisplay + 10;
134 		m->crtc_hsync_end = m->crtc_htotal - 92;
135 		m->crtc_vsync_start = m->crtc_vdisplay + 1;
136 		m->crtc_vsync_end = m->crtc_vsync_start + 1;
137 	}
138 
139 	decon_set_bits(ctx, DECON_VIDCON0, VIDCON0_ENVID, 0);
140 
141 	/* enable clock gate */
142 	val = CMU_CLKGAGE_MODE_SFR_F | CMU_CLKGAGE_MODE_MEM_F;
143 	writel(val, ctx->addr + DECON_CMU);
144 
145 	/* lcd on and use command if */
146 	val = VIDOUT_LCD_ON;
147 	if (ctx->out_type == IFTYPE_I80)
148 		val |= VIDOUT_COMMAND_IF;
149 	else
150 		val |= VIDOUT_RGB_IF;
151 	writel(val, ctx->addr + DECON_VIDOUTCON0);
152 
153 	val = VIDTCON2_LINEVAL(m->vdisplay - 1) |
154 		VIDTCON2_HOZVAL(m->hdisplay - 1);
155 	writel(val, ctx->addr + DECON_VIDTCON2);
156 
157 	if (ctx->out_type != IFTYPE_I80) {
158 		val = VIDTCON00_VBPD_F(
159 				m->crtc_vtotal - m->crtc_vsync_end - 1) |
160 			VIDTCON00_VFPD_F(
161 				m->crtc_vsync_start - m->crtc_vdisplay - 1);
162 		writel(val, ctx->addr + DECON_VIDTCON00);
163 
164 		val = VIDTCON01_VSPW_F(
165 				m->crtc_vsync_end - m->crtc_vsync_start - 1);
166 		writel(val, ctx->addr + DECON_VIDTCON01);
167 
168 		val = VIDTCON10_HBPD_F(
169 				m->crtc_htotal - m->crtc_hsync_end - 1) |
170 			VIDTCON10_HFPD_F(
171 				m->crtc_hsync_start - m->crtc_hdisplay - 1);
172 		writel(val, ctx->addr + DECON_VIDTCON10);
173 
174 		val = VIDTCON11_HSPW_F(
175 				m->crtc_hsync_end - m->crtc_hsync_start - 1);
176 		writel(val, ctx->addr + DECON_VIDTCON11);
177 	}
178 
179 	decon_setup_trigger(ctx);
180 
181 	/* enable output and display signal */
182 	decon_set_bits(ctx, DECON_VIDCON0, VIDCON0_ENVID | VIDCON0_ENVID_F, ~0);
183 
184 	decon_set_bits(ctx, DECON_UPDATE, STANDALONE_UPDATE_F, ~0);
185 }
186 
decon_win_set_pixfmt(struct decon_context * ctx,unsigned int win,struct drm_framebuffer * fb)187 static void decon_win_set_pixfmt(struct decon_context *ctx, unsigned int win,
188 				 struct drm_framebuffer *fb)
189 {
190 	unsigned long val;
191 
192 	val = readl(ctx->addr + DECON_WINCONx(win));
193 	val &= WINCONx_ENWIN_F;
194 
195 	switch (fb->pixel_format) {
196 	case DRM_FORMAT_XRGB1555:
197 		val |= WINCONx_BPPMODE_16BPP_I1555;
198 		val |= WINCONx_HAWSWP_F;
199 		val |= WINCONx_BURSTLEN_16WORD;
200 		break;
201 	case DRM_FORMAT_RGB565:
202 		val |= WINCONx_BPPMODE_16BPP_565;
203 		val |= WINCONx_HAWSWP_F;
204 		val |= WINCONx_BURSTLEN_16WORD;
205 		break;
206 	case DRM_FORMAT_XRGB8888:
207 		val |= WINCONx_BPPMODE_24BPP_888;
208 		val |= WINCONx_WSWP_F;
209 		val |= WINCONx_BURSTLEN_16WORD;
210 		break;
211 	case DRM_FORMAT_ARGB8888:
212 		val |= WINCONx_BPPMODE_32BPP_A8888;
213 		val |= WINCONx_WSWP_F | WINCONx_BLD_PIX_F | WINCONx_ALPHA_SEL_F;
214 		val |= WINCONx_BURSTLEN_16WORD;
215 		break;
216 	default:
217 		DRM_ERROR("Proper pixel format is not set\n");
218 		return;
219 	}
220 
221 	DRM_DEBUG_KMS("bpp = %u\n", fb->bits_per_pixel);
222 
223 	/*
224 	 * In case of exynos, setting dma-burst to 16Word causes permanent
225 	 * tearing for very small buffers, e.g. cursor buffer. Burst Mode
226 	 * switching which is based on plane size is not recommended as
227 	 * plane size varies a lot towards the end of the screen and rapid
228 	 * movement causes unstable DMA which results into iommu crash/tear.
229 	 */
230 
231 	if (fb->width < MIN_FB_WIDTH_FOR_16WORD_BURST) {
232 		val &= ~WINCONx_BURSTLEN_MASK;
233 		val |= WINCONx_BURSTLEN_8WORD;
234 	}
235 
236 	writel(val, ctx->addr + DECON_WINCONx(win));
237 }
238 
decon_shadow_protect_win(struct decon_context * ctx,int win,bool protect)239 static void decon_shadow_protect_win(struct decon_context *ctx, int win,
240 					bool protect)
241 {
242 	decon_set_bits(ctx, DECON_SHADOWCON, SHADOWCON_Wx_PROTECT(win),
243 		       protect ? ~0 : 0);
244 }
245 
decon_atomic_begin(struct exynos_drm_crtc * crtc,struct exynos_drm_plane * plane)246 static void decon_atomic_begin(struct exynos_drm_crtc *crtc,
247 					struct exynos_drm_plane *plane)
248 {
249 	struct decon_context *ctx = crtc->ctx;
250 
251 	if (test_bit(BIT_SUSPENDED, &ctx->flags))
252 		return;
253 
254 	decon_shadow_protect_win(ctx, plane->zpos, true);
255 }
256 
257 #define BIT_VAL(x, e, s) (((x) & ((1 << ((e) - (s) + 1)) - 1)) << (s))
258 #define COORDINATE_X(x) BIT_VAL((x), 23, 12)
259 #define COORDINATE_Y(x) BIT_VAL((x), 11, 0)
260 
decon_update_plane(struct exynos_drm_crtc * crtc,struct exynos_drm_plane * plane)261 static void decon_update_plane(struct exynos_drm_crtc *crtc,
262 			       struct exynos_drm_plane *plane)
263 {
264 	struct decon_context *ctx = crtc->ctx;
265 	struct drm_plane_state *state = plane->base.state;
266 	unsigned int win = plane->zpos;
267 	unsigned int bpp = state->fb->bits_per_pixel >> 3;
268 	unsigned int pitch = state->fb->pitches[0];
269 	u32 val;
270 
271 	if (test_bit(BIT_SUSPENDED, &ctx->flags))
272 		return;
273 
274 	val = COORDINATE_X(plane->crtc_x) | COORDINATE_Y(plane->crtc_y);
275 	writel(val, ctx->addr + DECON_VIDOSDxA(win));
276 
277 	val = COORDINATE_X(plane->crtc_x + plane->crtc_w - 1) |
278 		COORDINATE_Y(plane->crtc_y + plane->crtc_h - 1);
279 	writel(val, ctx->addr + DECON_VIDOSDxB(win));
280 
281 	val = VIDOSD_Wx_ALPHA_R_F(0xff) | VIDOSD_Wx_ALPHA_G_F(0xff) |
282 		VIDOSD_Wx_ALPHA_B_F(0xff);
283 	writel(val, ctx->addr + DECON_VIDOSDxC(win));
284 
285 	val = VIDOSD_Wx_ALPHA_R_F(0x0) | VIDOSD_Wx_ALPHA_G_F(0x0) |
286 		VIDOSD_Wx_ALPHA_B_F(0x0);
287 	writel(val, ctx->addr + DECON_VIDOSDxD(win));
288 
289 	writel(plane->dma_addr[0], ctx->addr + DECON_VIDW0xADD0B0(win));
290 
291 	val = plane->dma_addr[0] + pitch * plane->crtc_h;
292 	writel(val, ctx->addr + DECON_VIDW0xADD1B0(win));
293 
294 	if (ctx->out_type != IFTYPE_HDMI)
295 		val = BIT_VAL(pitch - plane->crtc_w * bpp, 27, 14)
296 			| BIT_VAL(plane->crtc_w * bpp, 13, 0);
297 	else
298 		val = BIT_VAL(pitch - plane->crtc_w * bpp, 29, 15)
299 			| BIT_VAL(plane->crtc_w * bpp, 14, 0);
300 	writel(val, ctx->addr + DECON_VIDW0xADD2(win));
301 
302 	decon_win_set_pixfmt(ctx, win, state->fb);
303 
304 	/* window enable */
305 	decon_set_bits(ctx, DECON_WINCONx(win), WINCONx_ENWIN_F, ~0);
306 
307 	/* standalone update */
308 	decon_set_bits(ctx, DECON_UPDATE, STANDALONE_UPDATE_F, ~0);
309 }
310 
decon_disable_plane(struct exynos_drm_crtc * crtc,struct exynos_drm_plane * plane)311 static void decon_disable_plane(struct exynos_drm_crtc *crtc,
312 				struct exynos_drm_plane *plane)
313 {
314 	struct decon_context *ctx = crtc->ctx;
315 	unsigned int win = plane->zpos;
316 
317 	if (test_bit(BIT_SUSPENDED, &ctx->flags))
318 		return;
319 
320 	decon_shadow_protect_win(ctx, win, true);
321 
322 	/* window disable */
323 	decon_set_bits(ctx, DECON_WINCONx(win), WINCONx_ENWIN_F, 0);
324 
325 	decon_shadow_protect_win(ctx, win, false);
326 
327 	/* standalone update */
328 	decon_set_bits(ctx, DECON_UPDATE, STANDALONE_UPDATE_F, ~0);
329 }
330 
decon_atomic_flush(struct exynos_drm_crtc * crtc,struct exynos_drm_plane * plane)331 static void decon_atomic_flush(struct exynos_drm_crtc *crtc,
332 				struct exynos_drm_plane *plane)
333 {
334 	struct decon_context *ctx = crtc->ctx;
335 
336 	if (test_bit(BIT_SUSPENDED, &ctx->flags))
337 		return;
338 
339 	decon_shadow_protect_win(ctx, plane->zpos, false);
340 
341 	if (ctx->out_type == IFTYPE_I80)
342 		set_bit(BIT_WIN_UPDATED, &ctx->flags);
343 }
344 
decon_swreset(struct decon_context * ctx)345 static void decon_swreset(struct decon_context *ctx)
346 {
347 	unsigned int tries;
348 
349 	writel(0, ctx->addr + DECON_VIDCON0);
350 	for (tries = 2000; tries; --tries) {
351 		if (~readl(ctx->addr + DECON_VIDCON0) & VIDCON0_STOP_STATUS)
352 			break;
353 		udelay(10);
354 	}
355 
356 	WARN(tries == 0, "failed to disable DECON\n");
357 
358 	writel(VIDCON0_SWRESET, ctx->addr + DECON_VIDCON0);
359 	for (tries = 2000; tries; --tries) {
360 		if (~readl(ctx->addr + DECON_VIDCON0) & VIDCON0_SWRESET)
361 			break;
362 		udelay(10);
363 	}
364 
365 	WARN(tries == 0, "failed to software reset DECON\n");
366 
367 	if (ctx->out_type != IFTYPE_HDMI)
368 		return;
369 
370 	writel(VIDCON0_CLKVALUP | VIDCON0_VLCKFREE, ctx->addr + DECON_VIDCON0);
371 	decon_set_bits(ctx, DECON_CMU,
372 		       CMU_CLKGAGE_MODE_SFR_F | CMU_CLKGAGE_MODE_MEM_F, ~0);
373 	writel(VIDCON1_VCLK_RUN_VDEN_DISABLE, ctx->addr + DECON_VIDCON1);
374 	writel(CRCCTRL_CRCEN | CRCCTRL_CRCSTART_F | CRCCTRL_CRCCLKEN,
375 	       ctx->addr + DECON_CRCCTRL);
376 	decon_setup_trigger(ctx);
377 }
378 
decon_enable(struct exynos_drm_crtc * crtc)379 static void decon_enable(struct exynos_drm_crtc *crtc)
380 {
381 	struct decon_context *ctx = crtc->ctx;
382 	int ret;
383 	int i;
384 
385 	if (!test_and_clear_bit(BIT_SUSPENDED, &ctx->flags))
386 		return;
387 
388 	pm_runtime_get_sync(ctx->dev);
389 
390 	for (i = 0; i < ARRAY_SIZE(decon_clks_name); i++) {
391 		ret = clk_prepare_enable(ctx->clks[i]);
392 		if (ret < 0)
393 			goto err;
394 	}
395 
396 	set_bit(BIT_CLKS_ENABLED, &ctx->flags);
397 
398 	/* if vblank was enabled status, enable it again. */
399 	if (test_and_clear_bit(BIT_IRQS_ENABLED, &ctx->flags))
400 		decon_enable_vblank(ctx->crtc);
401 
402 	decon_commit(ctx->crtc);
403 
404 	return;
405 err:
406 	while (--i >= 0)
407 		clk_disable_unprepare(ctx->clks[i]);
408 
409 	set_bit(BIT_SUSPENDED, &ctx->flags);
410 }
411 
decon_disable(struct exynos_drm_crtc * crtc)412 static void decon_disable(struct exynos_drm_crtc *crtc)
413 {
414 	struct decon_context *ctx = crtc->ctx;
415 	int i;
416 
417 	if (test_bit(BIT_SUSPENDED, &ctx->flags))
418 		return;
419 
420 	/*
421 	 * We need to make sure that all windows are disabled before we
422 	 * suspend that connector. Otherwise we might try to scan from
423 	 * a destroyed buffer later.
424 	 */
425 	for (i = ctx->first_win; i < WINDOWS_NR; i++)
426 		decon_disable_plane(crtc, &ctx->planes[i]);
427 
428 	decon_swreset(ctx);
429 
430 	for (i = 0; i < ARRAY_SIZE(decon_clks_name); i++)
431 		clk_disable_unprepare(ctx->clks[i]);
432 
433 	clear_bit(BIT_CLKS_ENABLED, &ctx->flags);
434 
435 	pm_runtime_put_sync(ctx->dev);
436 
437 	set_bit(BIT_SUSPENDED, &ctx->flags);
438 }
439 
decon_te_irq_handler(struct exynos_drm_crtc * crtc)440 void decon_te_irq_handler(struct exynos_drm_crtc *crtc)
441 {
442 	struct decon_context *ctx = crtc->ctx;
443 
444 	if (!test_bit(BIT_CLKS_ENABLED, &ctx->flags))
445 		return;
446 
447 	if (test_and_clear_bit(BIT_WIN_UPDATED, &ctx->flags))
448 		decon_set_bits(ctx, DECON_TRIGCON, TRIGCON_SWTRIGCMD, ~0);
449 
450 	drm_crtc_handle_vblank(&ctx->crtc->base);
451 }
452 
decon_clear_channels(struct exynos_drm_crtc * crtc)453 static void decon_clear_channels(struct exynos_drm_crtc *crtc)
454 {
455 	struct decon_context *ctx = crtc->ctx;
456 	int win, i, ret;
457 
458 	DRM_DEBUG_KMS("%s\n", __FILE__);
459 
460 	for (i = 0; i < ARRAY_SIZE(decon_clks_name); i++) {
461 		ret = clk_prepare_enable(ctx->clks[i]);
462 		if (ret < 0)
463 			goto err;
464 	}
465 
466 	for (win = 0; win < WINDOWS_NR; win++) {
467 		decon_shadow_protect_win(ctx, win, true);
468 		decon_set_bits(ctx, DECON_WINCONx(win), WINCONx_ENWIN_F, 0);
469 		decon_shadow_protect_win(ctx, win, false);
470 		decon_set_bits(ctx, DECON_UPDATE, STANDALONE_UPDATE_F, ~0);
471 	}
472 	/* TODO: wait for possible vsync */
473 	msleep(50);
474 
475 err:
476 	while (--i >= 0)
477 		clk_disable_unprepare(ctx->clks[i]);
478 }
479 
480 static struct exynos_drm_crtc_ops decon_crtc_ops = {
481 	.enable			= decon_enable,
482 	.disable		= decon_disable,
483 	.commit			= decon_commit,
484 	.enable_vblank		= decon_enable_vblank,
485 	.disable_vblank		= decon_disable_vblank,
486 	.atomic_begin		= decon_atomic_begin,
487 	.update_plane		= decon_update_plane,
488 	.disable_plane		= decon_disable_plane,
489 	.atomic_flush		= decon_atomic_flush,
490 	.te_handler		= decon_te_irq_handler,
491 };
492 
decon_bind(struct device * dev,struct device * master,void * data)493 static int decon_bind(struct device *dev, struct device *master, void *data)
494 {
495 	struct decon_context *ctx = dev_get_drvdata(dev);
496 	struct drm_device *drm_dev = data;
497 	struct exynos_drm_private *priv = drm_dev->dev_private;
498 	struct exynos_drm_plane *exynos_plane;
499 	enum exynos_drm_output_type out_type;
500 	enum drm_plane_type type;
501 	unsigned int win;
502 	int ret;
503 
504 	ctx->drm_dev = drm_dev;
505 	ctx->pipe = priv->pipe++;
506 
507 	for (win = ctx->first_win; win < WINDOWS_NR; win++) {
508 		int tmp = (win == ctx->first_win) ? 0 : win;
509 
510 		type = exynos_plane_get_type(tmp, CURSOR_WIN);
511 		ret = exynos_plane_init(drm_dev, &ctx->planes[win],
512 				1 << ctx->pipe, type, decon_formats,
513 				ARRAY_SIZE(decon_formats), win);
514 		if (ret)
515 			return ret;
516 	}
517 
518 	exynos_plane = &ctx->planes[ctx->first_win];
519 	out_type = (ctx->out_type == IFTYPE_HDMI) ? EXYNOS_DISPLAY_TYPE_HDMI
520 						  : EXYNOS_DISPLAY_TYPE_LCD;
521 	ctx->crtc = exynos_drm_crtc_create(drm_dev, &exynos_plane->base,
522 					ctx->pipe, out_type,
523 					&decon_crtc_ops, ctx);
524 	if (IS_ERR(ctx->crtc)) {
525 		ret = PTR_ERR(ctx->crtc);
526 		goto err;
527 	}
528 
529 	decon_clear_channels(ctx->crtc);
530 
531 	ret = drm_iommu_attach_device(drm_dev, dev);
532 	if (ret)
533 		goto err;
534 
535 	return ret;
536 err:
537 	priv->pipe--;
538 	return ret;
539 }
540 
decon_unbind(struct device * dev,struct device * master,void * data)541 static void decon_unbind(struct device *dev, struct device *master, void *data)
542 {
543 	struct decon_context *ctx = dev_get_drvdata(dev);
544 
545 	decon_disable(ctx->crtc);
546 
547 	/* detach this sub driver from iommu mapping if supported. */
548 	drm_iommu_detach_device(ctx->drm_dev, ctx->dev);
549 }
550 
551 static const struct component_ops decon_component_ops = {
552 	.bind	= decon_bind,
553 	.unbind = decon_unbind,
554 };
555 
decon_irq_handler(int irq,void * dev_id)556 static irqreturn_t decon_irq_handler(int irq, void *dev_id)
557 {
558 	struct decon_context *ctx = dev_id;
559 	u32 val;
560 	int win;
561 
562 	if (!test_bit(BIT_CLKS_ENABLED, &ctx->flags))
563 		goto out;
564 
565 	val = readl(ctx->addr + DECON_VIDINTCON1);
566 	val &= VIDINTCON1_INTFRMDONEPEND | VIDINTCON1_INTFRMPEND;
567 
568 	if (val) {
569 		for (win = ctx->first_win; win < WINDOWS_NR ; win++) {
570 			struct exynos_drm_plane *plane = &ctx->planes[win];
571 
572 			if (!plane->pending_fb)
573 				continue;
574 
575 			exynos_drm_crtc_finish_update(ctx->crtc, plane);
576 		}
577 
578 		/* clear */
579 		writel(val, ctx->addr + DECON_VIDINTCON1);
580 	}
581 
582 out:
583 	return IRQ_HANDLED;
584 }
585 
586 static const struct of_device_id exynos5433_decon_driver_dt_match[] = {
587 	{
588 		.compatible = "samsung,exynos5433-decon",
589 		.data = (void *)IFTYPE_RGB
590 	},
591 	{
592 		.compatible = "samsung,exynos5433-decon-tv",
593 		.data = (void *)IFTYPE_HDMI
594 	},
595 	{},
596 };
597 MODULE_DEVICE_TABLE(of, exynos5433_decon_driver_dt_match);
598 
exynos5433_decon_probe(struct platform_device * pdev)599 static int exynos5433_decon_probe(struct platform_device *pdev)
600 {
601 	const struct of_device_id *of_id;
602 	struct device *dev = &pdev->dev;
603 	struct decon_context *ctx;
604 	struct resource *res;
605 	int ret;
606 	int i;
607 
608 	ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
609 	if (!ctx)
610 		return -ENOMEM;
611 
612 	__set_bit(BIT_SUSPENDED, &ctx->flags);
613 	ctx->dev = dev;
614 
615 	of_id = of_match_device(exynos5433_decon_driver_dt_match, &pdev->dev);
616 	ctx->out_type = (enum decon_iftype)of_id->data;
617 
618 	if (ctx->out_type == IFTYPE_HDMI)
619 		ctx->first_win = 1;
620 	else if (of_get_child_by_name(dev->of_node, "i80-if-timings"))
621 		ctx->out_type = IFTYPE_I80;
622 
623 	for (i = 0; i < ARRAY_SIZE(decon_clks_name); i++) {
624 		struct clk *clk;
625 
626 		clk = devm_clk_get(ctx->dev, decon_clks_name[i]);
627 		if (IS_ERR(clk))
628 			return PTR_ERR(clk);
629 
630 		ctx->clks[i] = clk;
631 	}
632 
633 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
634 	if (!res) {
635 		dev_err(dev, "cannot find IO resource\n");
636 		return -ENXIO;
637 	}
638 
639 	ctx->addr = devm_ioremap_resource(dev, res);
640 	if (IS_ERR(ctx->addr)) {
641 		dev_err(dev, "ioremap failed\n");
642 		return PTR_ERR(ctx->addr);
643 	}
644 
645 	res = platform_get_resource_byname(pdev, IORESOURCE_IRQ,
646 			(ctx->out_type == IFTYPE_I80) ? "lcd_sys" : "vsync");
647 	if (!res) {
648 		dev_err(dev, "cannot find IRQ resource\n");
649 		return -ENXIO;
650 	}
651 
652 	ret = devm_request_irq(dev, res->start, decon_irq_handler, 0,
653 			       "drm_decon", ctx);
654 	if (ret < 0) {
655 		dev_err(dev, "lcd_sys irq request failed\n");
656 		return ret;
657 	}
658 
659 	platform_set_drvdata(pdev, ctx);
660 
661 	pm_runtime_enable(dev);
662 
663 	ret = component_add(dev, &decon_component_ops);
664 	if (ret)
665 		goto err_disable_pm_runtime;
666 
667 	return 0;
668 
669 err_disable_pm_runtime:
670 	pm_runtime_disable(dev);
671 
672 	return ret;
673 }
674 
exynos5433_decon_remove(struct platform_device * pdev)675 static int exynos5433_decon_remove(struct platform_device *pdev)
676 {
677 	pm_runtime_disable(&pdev->dev);
678 
679 	component_del(&pdev->dev, &decon_component_ops);
680 
681 	return 0;
682 }
683 
684 struct platform_driver exynos5433_decon_driver = {
685 	.probe		= exynos5433_decon_probe,
686 	.remove		= exynos5433_decon_remove,
687 	.driver		= {
688 		.name	= "exynos5433-decon",
689 		.of_match_table = exynos5433_decon_driver_dt_match,
690 	},
691 };
692