Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.1.
  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/iopoll.h>
 17#include <linux/irq.h>
 18#include <linux/mfd/syscon.h>
 19#include <linux/of_device.h>
 20#include <linux/of_gpio.h>
 21#include <linux/pm_runtime.h>
 22#include <linux/regmap.h>
 23
 24#include "exynos_drm_drv.h"
 25#include "exynos_drm_crtc.h"
 26#include "exynos_drm_fb.h"
 27#include "exynos_drm_plane.h"
 28#include "exynos_drm_iommu.h"
 29#include "regs-decon5433.h"
 30
 31#define DSD_CFG_MUX 0x1004
 32#define DSD_CFG_MUX_TE_UNMASK_GLOBAL BIT(13)
 33
 34#define WINDOWS_NR	3
 35#define MIN_FB_WIDTH_FOR_16WORD_BURST	128
 36
 37#define I80_HW_TRG	(1 << 0)
 38#define IFTYPE_HDMI	(1 << 1)
 39
 40static const char * const decon_clks_name[] = {
 41	"pclk",
 42	"aclk_decon",
 43	"aclk_smmu_decon0x",
 44	"aclk_xiu_decon0x",
 45	"pclk_smmu_decon0x",
 46	"sclk_decon_vclk",
 47	"sclk_decon_eclk",
 48};
 49
 50struct decon_context {
 51	struct device			*dev;
 52	struct drm_device		*drm_dev;
 53	struct exynos_drm_crtc		*crtc;
 54	struct exynos_drm_plane		planes[WINDOWS_NR];
 55	struct exynos_drm_plane_config	configs[WINDOWS_NR];
 56	void __iomem			*addr;
 57	struct regmap			*sysreg;
 58	struct clk			*clks[ARRAY_SIZE(decon_clks_name)];
 59	unsigned int			irq;
 60	unsigned int			irq_vsync;
 61	unsigned int			irq_lcd_sys;
 62	unsigned int			te_irq;
 63	unsigned long			out_type;
 64	int				first_win;
 65	spinlock_t			vblank_lock;
 66	u32				frame_id;
 67};
 68
 69static const uint32_t decon_formats[] = {
 70	DRM_FORMAT_XRGB1555,
 71	DRM_FORMAT_RGB565,
 72	DRM_FORMAT_XRGB8888,
 73	DRM_FORMAT_ARGB8888,
 74};
 75
 76static const enum drm_plane_type decon_win_types[WINDOWS_NR] = {
 77	DRM_PLANE_TYPE_PRIMARY,
 78	DRM_PLANE_TYPE_OVERLAY,
 79	DRM_PLANE_TYPE_CURSOR,
 80};
 81
 82static inline void decon_set_bits(struct decon_context *ctx, u32 reg, u32 mask,
 83				  u32 val)
 84{
 85	val = (val & mask) | (readl(ctx->addr + reg) & ~mask);
 86	writel(val, ctx->addr + reg);
 87}
 88
 89static int decon_enable_vblank(struct exynos_drm_crtc *crtc)
 90{
 91	struct decon_context *ctx = crtc->ctx;
 92	u32 val;
 93
 94	val = VIDINTCON0_INTEN;
 95	if (crtc->i80_mode)
 96		val |= VIDINTCON0_FRAMEDONE;
 97	else
 98		val |= VIDINTCON0_INTFRMEN | VIDINTCON0_FRAMESEL_FP;
 99
100	writel(val, ctx->addr + DECON_VIDINTCON0);
101
102	enable_irq(ctx->irq);
103	if (!(ctx->out_type & I80_HW_TRG))
104		enable_irq(ctx->te_irq);
105
106	return 0;
107}
108
109static void decon_disable_vblank(struct exynos_drm_crtc *crtc)
110{
111	struct decon_context *ctx = crtc->ctx;
112
113	if (!(ctx->out_type & I80_HW_TRG))
114		disable_irq_nosync(ctx->te_irq);
115	disable_irq_nosync(ctx->irq);
116
117	writel(0, ctx->addr + DECON_VIDINTCON0);
118}
119
120/* return number of starts/ends of frame transmissions since reset */
121static u32 decon_get_frame_count(struct decon_context *ctx, bool end)
122{
123	u32 frm, pfrm, status, cnt = 2;
124
125	/* To get consistent result repeat read until frame id is stable.
126	 * Usually the loop will be executed once, in rare cases when the loop
127	 * is executed at frame change time 2nd pass will be needed.
128	 */
129	frm = readl(ctx->addr + DECON_CRFMID);
130	do {
131		status = readl(ctx->addr + DECON_VIDCON1);
132		pfrm = frm;
133		frm = readl(ctx->addr + DECON_CRFMID);
134	} while (frm != pfrm && --cnt);
135
136	/* CRFMID is incremented on BPORCH in case of I80 and on VSYNC in case
137	 * of RGB, it should be taken into account.
138	 */
139	if (!frm)
140		return 0;
141
142	switch (status & (VIDCON1_VSTATUS_MASK | VIDCON1_I80_ACTIVE)) {
143	case VIDCON1_VSTATUS_VS:
144		if (!(ctx->crtc->i80_mode))
145			--frm;
146		break;
147	case VIDCON1_VSTATUS_BP:
148		--frm;
149		break;
150	case VIDCON1_I80_ACTIVE:
151	case VIDCON1_VSTATUS_AC:
152		if (end)
153			--frm;
154		break;
155	default:
156		break;
157	}
158
159	return frm;
160}
161
162static u32 decon_get_vblank_counter(struct exynos_drm_crtc *crtc)
163{
164	struct decon_context *ctx = crtc->ctx;
165
166	return decon_get_frame_count(ctx, false);
167}
168
169static void decon_setup_trigger(struct decon_context *ctx)
170{
171	if (!ctx->crtc->i80_mode && !(ctx->out_type & I80_HW_TRG))
172		return;
173
174	if (!(ctx->out_type & I80_HW_TRG)) {
175		writel(TRIGCON_TRIGEN_PER_F | TRIGCON_TRIGEN_F |
176		       TRIGCON_TE_AUTO_MASK | TRIGCON_SWTRIGEN,
177		       ctx->addr + DECON_TRIGCON);
178		return;
179	}
180
181	writel(TRIGCON_TRIGEN_PER_F | TRIGCON_TRIGEN_F | TRIGCON_HWTRIGMASK
182	       | TRIGCON_HWTRIGEN, ctx->addr + DECON_TRIGCON);
183
184	if (regmap_update_bits(ctx->sysreg, DSD_CFG_MUX,
185			       DSD_CFG_MUX_TE_UNMASK_GLOBAL, ~0))
186		DRM_ERROR("Cannot update sysreg.\n");
187}
188
189static void decon_commit(struct exynos_drm_crtc *crtc)
190{
191	struct decon_context *ctx = crtc->ctx;
192	struct drm_display_mode *m = &crtc->base.mode;
193	bool interlaced = false;
194	u32 val;
195
196	if (ctx->out_type & IFTYPE_HDMI) {
197		m->crtc_hsync_start = m->crtc_hdisplay + 10;
198		m->crtc_hsync_end = m->crtc_htotal - 92;
199		m->crtc_vsync_start = m->crtc_vdisplay + 1;
200		m->crtc_vsync_end = m->crtc_vsync_start + 1;
201		if (m->flags & DRM_MODE_FLAG_INTERLACE)
202			interlaced = true;
203	}
204
205	decon_setup_trigger(ctx);
206
207	/* lcd on and use command if */
208	val = VIDOUT_LCD_ON;
209	if (interlaced)
210		val |= VIDOUT_INTERLACE_EN_F;
211	if (crtc->i80_mode) {
212		val |= VIDOUT_COMMAND_IF;
213	} else {
214		val |= VIDOUT_RGB_IF;
215	}
216
217	writel(val, ctx->addr + DECON_VIDOUTCON0);
218
219	if (interlaced)
220		val = VIDTCON2_LINEVAL(m->vdisplay / 2 - 1) |
221			VIDTCON2_HOZVAL(m->hdisplay - 1);
222	else
223		val = VIDTCON2_LINEVAL(m->vdisplay - 1) |
224			VIDTCON2_HOZVAL(m->hdisplay - 1);
225	writel(val, ctx->addr + DECON_VIDTCON2);
226
227	if (!crtc->i80_mode) {
228		int vbp = m->crtc_vtotal - m->crtc_vsync_end;
229		int vfp = m->crtc_vsync_start - m->crtc_vdisplay;
230
231		if (interlaced)
232			vbp = vbp / 2 - 1;
233		val = VIDTCON00_VBPD_F(vbp - 1) | VIDTCON00_VFPD_F(vfp - 1);
234		writel(val, ctx->addr + DECON_VIDTCON00);
235
236		val = VIDTCON01_VSPW_F(
237				m->crtc_vsync_end - m->crtc_vsync_start - 1);
238		writel(val, ctx->addr + DECON_VIDTCON01);
239
240		val = VIDTCON10_HBPD_F(
241				m->crtc_htotal - m->crtc_hsync_end - 1) |
242			VIDTCON10_HFPD_F(
243				m->crtc_hsync_start - m->crtc_hdisplay - 1);
244		writel(val, ctx->addr + DECON_VIDTCON10);
245
246		val = VIDTCON11_HSPW_F(
247				m->crtc_hsync_end - m->crtc_hsync_start - 1);
248		writel(val, ctx->addr + DECON_VIDTCON11);
249	}
250
251	/* enable output and display signal */
252	decon_set_bits(ctx, DECON_VIDCON0, VIDCON0_ENVID | VIDCON0_ENVID_F, ~0);
253
254	decon_set_bits(ctx, DECON_UPDATE, STANDALONE_UPDATE_F, ~0);
255}
256
257static void decon_win_set_pixfmt(struct decon_context *ctx, unsigned int win,
258				 struct drm_framebuffer *fb)
259{
260	unsigned long val;
261
262	val = readl(ctx->addr + DECON_WINCONx(win));
263	val &= ~WINCONx_BPPMODE_MASK;
264
265	switch (fb->format->format) {
266	case DRM_FORMAT_XRGB1555:
267		val |= WINCONx_BPPMODE_16BPP_I1555;
268		val |= WINCONx_HAWSWP_F;
269		val |= WINCONx_BURSTLEN_16WORD;
270		break;
271	case DRM_FORMAT_RGB565:
272		val |= WINCONx_BPPMODE_16BPP_565;
273		val |= WINCONx_HAWSWP_F;
274		val |= WINCONx_BURSTLEN_16WORD;
275		break;
276	case DRM_FORMAT_XRGB8888:
277		val |= WINCONx_BPPMODE_24BPP_888;
278		val |= WINCONx_WSWP_F;
279		val |= WINCONx_BURSTLEN_16WORD;
280		break;
281	case DRM_FORMAT_ARGB8888:
282	default:
283		val |= WINCONx_BPPMODE_32BPP_A8888;
284		val |= WINCONx_WSWP_F | WINCONx_BLD_PIX_F | WINCONx_ALPHA_SEL_F;
285		val |= WINCONx_BURSTLEN_16WORD;
286		break;
287	}
288
289	DRM_DEBUG_KMS("cpp = %u\n", fb->format->cpp[0]);
290
291	/*
292	 * In case of exynos, setting dma-burst to 16Word causes permanent
293	 * tearing for very small buffers, e.g. cursor buffer. Burst Mode
294	 * switching which is based on plane size is not recommended as
295	 * plane size varies a lot towards the end of the screen and rapid
296	 * movement causes unstable DMA which results into iommu crash/tear.
297	 */
298
299	if (fb->width < MIN_FB_WIDTH_FOR_16WORD_BURST) {
300		val &= ~WINCONx_BURSTLEN_MASK;
301		val |= WINCONx_BURSTLEN_8WORD;
302	}
303
304	writel(val, ctx->addr + DECON_WINCONx(win));
305}
306
307static void decon_shadow_protect(struct decon_context *ctx, bool protect)
308{
309	decon_set_bits(ctx, DECON_SHADOWCON, SHADOWCON_PROTECT_MASK,
310		       protect ? ~0 : 0);
311}
312
313static void decon_atomic_begin(struct exynos_drm_crtc *crtc)
314{
315	struct decon_context *ctx = crtc->ctx;
316
317	decon_shadow_protect(ctx, true);
318}
319
320#define BIT_VAL(x, e, s) (((x) & ((1 << ((e) - (s) + 1)) - 1)) << (s))
321#define COORDINATE_X(x) BIT_VAL((x), 23, 12)
322#define COORDINATE_Y(x) BIT_VAL((x), 11, 0)
323
324static void decon_update_plane(struct exynos_drm_crtc *crtc,
325			       struct exynos_drm_plane *plane)
326{
327	struct exynos_drm_plane_state *state =
328				to_exynos_plane_state(plane->base.state);
329	struct decon_context *ctx = crtc->ctx;
330	struct drm_framebuffer *fb = state->base.fb;
331	unsigned int win = plane->index;
332	unsigned int cpp = fb->format->cpp[0];
333	unsigned int pitch = fb->pitches[0];
334	dma_addr_t dma_addr = exynos_drm_fb_dma_addr(fb, 0);
335	u32 val;
336
337	if (crtc->base.mode.flags & DRM_MODE_FLAG_INTERLACE) {
338		val = COORDINATE_X(state->crtc.x) |
339			COORDINATE_Y(state->crtc.y / 2);
340		writel(val, ctx->addr + DECON_VIDOSDxA(win));
341
342		val = COORDINATE_X(state->crtc.x + state->crtc.w - 1) |
343			COORDINATE_Y((state->crtc.y + state->crtc.h) / 2 - 1);
344		writel(val, ctx->addr + DECON_VIDOSDxB(win));
345	} else {
346		val = COORDINATE_X(state->crtc.x) | COORDINATE_Y(state->crtc.y);
347		writel(val, ctx->addr + DECON_VIDOSDxA(win));
348
349		val = COORDINATE_X(state->crtc.x + state->crtc.w - 1) |
350				COORDINATE_Y(state->crtc.y + state->crtc.h - 1);
351		writel(val, ctx->addr + DECON_VIDOSDxB(win));
352	}
353
354	val = VIDOSD_Wx_ALPHA_R_F(0x0) | VIDOSD_Wx_ALPHA_G_F(0x0) |
355		VIDOSD_Wx_ALPHA_B_F(0x0);
356	writel(val, ctx->addr + DECON_VIDOSDxC(win));
357
358	val = VIDOSD_Wx_ALPHA_R_F(0x0) | VIDOSD_Wx_ALPHA_G_F(0x0) |
359		VIDOSD_Wx_ALPHA_B_F(0x0);
360	writel(val, ctx->addr + DECON_VIDOSDxD(win));
361
362	writel(dma_addr, ctx->addr + DECON_VIDW0xADD0B0(win));
363
364	val = dma_addr + pitch * state->src.h;
365	writel(val, ctx->addr + DECON_VIDW0xADD1B0(win));
366
367	if (!(ctx->out_type & IFTYPE_HDMI))
368		val = BIT_VAL(pitch - state->crtc.w * cpp, 27, 14)
369			| BIT_VAL(state->crtc.w * cpp, 13, 0);
370	else
371		val = BIT_VAL(pitch - state->crtc.w * cpp, 29, 15)
372			| BIT_VAL(state->crtc.w * cpp, 14, 0);
373	writel(val, ctx->addr + DECON_VIDW0xADD2(win));
374
375	decon_win_set_pixfmt(ctx, win, fb);
376
377	/* window enable */
378	decon_set_bits(ctx, DECON_WINCONx(win), WINCONx_ENWIN_F, ~0);
379}
380
381static void decon_disable_plane(struct exynos_drm_crtc *crtc,
382				struct exynos_drm_plane *plane)
383{
384	struct decon_context *ctx = crtc->ctx;
385	unsigned int win = plane->index;
386
387	decon_set_bits(ctx, DECON_WINCONx(win), WINCONx_ENWIN_F, 0);
388}
389
390static void decon_atomic_flush(struct exynos_drm_crtc *crtc)
391{
392	struct decon_context *ctx = crtc->ctx;
393	unsigned long flags;
394
395	spin_lock_irqsave(&ctx->vblank_lock, flags);
396
397	decon_shadow_protect(ctx, false);
398
399	decon_set_bits(ctx, DECON_UPDATE, STANDALONE_UPDATE_F, ~0);
400
401	ctx->frame_id = decon_get_frame_count(ctx, true);
402
403	exynos_crtc_handle_event(crtc);
404
405	spin_unlock_irqrestore(&ctx->vblank_lock, flags);
406}
407
408static void decon_swreset(struct decon_context *ctx)
409{
410	unsigned long flags;
411	u32 val;
412	int ret;
413
414	writel(0, ctx->addr + DECON_VIDCON0);
415	readl_poll_timeout(ctx->addr + DECON_VIDCON0, val,
416			   ~val & VIDCON0_STOP_STATUS, 12, 20000);
417
418	writel(VIDCON0_SWRESET, ctx->addr + DECON_VIDCON0);
419	ret = readl_poll_timeout(ctx->addr + DECON_VIDCON0, val,
420				 ~val & VIDCON0_SWRESET, 12, 20000);
421
422	WARN(ret < 0, "failed to software reset DECON\n");
423
424	spin_lock_irqsave(&ctx->vblank_lock, flags);
425	ctx->frame_id = 0;
426	spin_unlock_irqrestore(&ctx->vblank_lock, flags);
427
428	if (!(ctx->out_type & IFTYPE_HDMI))
429		return;
430
431	writel(VIDCON0_CLKVALUP | VIDCON0_VLCKFREE, ctx->addr + DECON_VIDCON0);
432	decon_set_bits(ctx, DECON_CMU,
433		       CMU_CLKGAGE_MODE_SFR_F | CMU_CLKGAGE_MODE_MEM_F, ~0);
434	writel(VIDCON1_VCLK_RUN_VDEN_DISABLE, ctx->addr + DECON_VIDCON1);
435	writel(CRCCTRL_CRCEN | CRCCTRL_CRCSTART_F | CRCCTRL_CRCCLKEN,
436	       ctx->addr + DECON_CRCCTRL);
437}
438
439static void decon_enable(struct exynos_drm_crtc *crtc)
440{
441	struct decon_context *ctx = crtc->ctx;
442
443	pm_runtime_get_sync(ctx->dev);
444
445	exynos_drm_pipe_clk_enable(crtc, true);
446
447	decon_swreset(ctx);
448
449	decon_commit(ctx->crtc);
450}
451
452static void decon_disable(struct exynos_drm_crtc *crtc)
453{
454	struct decon_context *ctx = crtc->ctx;
455	int i;
456
457	if (!(ctx->out_type & I80_HW_TRG))
458		synchronize_irq(ctx->te_irq);
459	synchronize_irq(ctx->irq);
460
461	/*
462	 * We need to make sure that all windows are disabled before we
463	 * suspend that connector. Otherwise we might try to scan from
464	 * a destroyed buffer later.
465	 */
466	for (i = ctx->first_win; i < WINDOWS_NR; i++)
467		decon_disable_plane(crtc, &ctx->planes[i]);
468
469	decon_swreset(ctx);
470
471	exynos_drm_pipe_clk_enable(crtc, false);
472
473	pm_runtime_put_sync(ctx->dev);
474}
475
476static irqreturn_t decon_te_irq_handler(int irq, void *dev_id)
477{
478	struct decon_context *ctx = dev_id;
479
480	decon_set_bits(ctx, DECON_TRIGCON, TRIGCON_SWTRIGCMD, ~0);
481
482	return IRQ_HANDLED;
483}
484
485static void decon_clear_channels(struct exynos_drm_crtc *crtc)
486{
487	struct decon_context *ctx = crtc->ctx;
488	int win, i, ret;
489
490	DRM_DEBUG_KMS("%s\n", __FILE__);
491
492	for (i = 0; i < ARRAY_SIZE(decon_clks_name); i++) {
493		ret = clk_prepare_enable(ctx->clks[i]);
494		if (ret < 0)
495			goto err;
496	}
497
498	decon_shadow_protect(ctx, true);
499	for (win = 0; win < WINDOWS_NR; win++)
500		decon_set_bits(ctx, DECON_WINCONx(win), WINCONx_ENWIN_F, 0);
501	decon_shadow_protect(ctx, false);
502
503	decon_set_bits(ctx, DECON_UPDATE, STANDALONE_UPDATE_F, ~0);
504
505	/* TODO: wait for possible vsync */
506	msleep(50);
507
508err:
509	while (--i >= 0)
510		clk_disable_unprepare(ctx->clks[i]);
511}
512
513static enum drm_mode_status decon_mode_valid(struct exynos_drm_crtc *crtc,
514		const struct drm_display_mode *mode)
515{
516	struct decon_context *ctx = crtc->ctx;
517
518	ctx->irq = crtc->i80_mode ? ctx->irq_lcd_sys : ctx->irq_vsync;
519
520	if (ctx->irq)
521		return MODE_OK;
522
523	dev_info(ctx->dev, "Sink requires %s mode, but appropriate interrupt is not provided.\n",
524			crtc->i80_mode ? "command" : "video");
525
526	return MODE_BAD;
527}
528
529static const struct exynos_drm_crtc_ops decon_crtc_ops = {
530	.enable			= decon_enable,
531	.disable		= decon_disable,
532	.enable_vblank		= decon_enable_vblank,
533	.disable_vblank		= decon_disable_vblank,
534	.get_vblank_counter	= decon_get_vblank_counter,
535	.atomic_begin		= decon_atomic_begin,
536	.update_plane		= decon_update_plane,
537	.disable_plane		= decon_disable_plane,
538	.mode_valid		= decon_mode_valid,
539	.atomic_flush		= decon_atomic_flush,
540};
541
542static int decon_bind(struct device *dev, struct device *master, void *data)
543{
544	struct decon_context *ctx = dev_get_drvdata(dev);
545	struct drm_device *drm_dev = data;
546	struct exynos_drm_plane *exynos_plane;
547	enum exynos_drm_output_type out_type;
548	unsigned int win;
549	int ret;
550
551	ctx->drm_dev = drm_dev;
552	drm_dev->max_vblank_count = 0xffffffff;
553
554	for (win = ctx->first_win; win < WINDOWS_NR; win++) {
555		int tmp = (win == ctx->first_win) ? 0 : win;
556
557		ctx->configs[win].pixel_formats = decon_formats;
558		ctx->configs[win].num_pixel_formats = ARRAY_SIZE(decon_formats);
559		ctx->configs[win].zpos = win;
560		ctx->configs[win].type = decon_win_types[tmp];
561
562		ret = exynos_plane_init(drm_dev, &ctx->planes[win], win,
563					&ctx->configs[win]);
564		if (ret)
565			return ret;
566	}
567
568	exynos_plane = &ctx->planes[ctx->first_win];
569	out_type = (ctx->out_type & IFTYPE_HDMI) ? EXYNOS_DISPLAY_TYPE_HDMI
570						  : EXYNOS_DISPLAY_TYPE_LCD;
571	ctx->crtc = exynos_drm_crtc_create(drm_dev, &exynos_plane->base,
572			out_type, &decon_crtc_ops, ctx);
573	if (IS_ERR(ctx->crtc))
574		return PTR_ERR(ctx->crtc);
575
576	decon_clear_channels(ctx->crtc);
577
578	return drm_iommu_attach_device(drm_dev, dev);
579}
580
581static void decon_unbind(struct device *dev, struct device *master, void *data)
582{
583	struct decon_context *ctx = dev_get_drvdata(dev);
584
585	decon_disable(ctx->crtc);
586
587	/* detach this sub driver from iommu mapping if supported. */
588	drm_iommu_detach_device(ctx->drm_dev, ctx->dev);
589}
590
591static const struct component_ops decon_component_ops = {
592	.bind	= decon_bind,
593	.unbind = decon_unbind,
594};
595
596static void decon_handle_vblank(struct decon_context *ctx)
597{
598	u32 frm;
599
600	spin_lock(&ctx->vblank_lock);
601
602	frm = decon_get_frame_count(ctx, true);
603
604	if (frm != ctx->frame_id) {
605		/* handle only if incremented, take care of wrap-around */
606		if ((s32)(frm - ctx->frame_id) > 0)
607			drm_crtc_handle_vblank(&ctx->crtc->base);
608		ctx->frame_id = frm;
609	}
610
611	spin_unlock(&ctx->vblank_lock);
612}
613
614static irqreturn_t decon_irq_handler(int irq, void *dev_id)
615{
616	struct decon_context *ctx = dev_id;
617	u32 val;
618
619	val = readl(ctx->addr + DECON_VIDINTCON1);
620	val &= VIDINTCON1_INTFRMDONEPEND | VIDINTCON1_INTFRMPEND;
621
622	if (val) {
623		writel(val, ctx->addr + DECON_VIDINTCON1);
624		if (ctx->out_type & IFTYPE_HDMI) {
625			val = readl(ctx->addr + DECON_VIDOUTCON0);
626			val &= VIDOUT_INTERLACE_EN_F | VIDOUT_INTERLACE_FIELD_F;
627			if (val ==
628			    (VIDOUT_INTERLACE_EN_F | VIDOUT_INTERLACE_FIELD_F))
629				return IRQ_HANDLED;
630		}
631		decon_handle_vblank(ctx);
632	}
633
634	return IRQ_HANDLED;
635}
636
637#ifdef CONFIG_PM
638static int exynos5433_decon_suspend(struct device *dev)
639{
640	struct decon_context *ctx = dev_get_drvdata(dev);
641	int i = ARRAY_SIZE(decon_clks_name);
642
643	while (--i >= 0)
644		clk_disable_unprepare(ctx->clks[i]);
645
646	return 0;
647}
648
649static int exynos5433_decon_resume(struct device *dev)
650{
651	struct decon_context *ctx = dev_get_drvdata(dev);
652	int i, ret;
653
654	for (i = 0; i < ARRAY_SIZE(decon_clks_name); i++) {
655		ret = clk_prepare_enable(ctx->clks[i]);
656		if (ret < 0)
657			goto err;
658	}
659
660	return 0;
661
662err:
663	while (--i >= 0)
664		clk_disable_unprepare(ctx->clks[i]);
665
666	return ret;
667}
668#endif
669
670static const struct dev_pm_ops exynos5433_decon_pm_ops = {
671	SET_RUNTIME_PM_OPS(exynos5433_decon_suspend, exynos5433_decon_resume,
672			   NULL)
673};
674
675static const struct of_device_id exynos5433_decon_driver_dt_match[] = {
676	{
677		.compatible = "samsung,exynos5433-decon",
678		.data = (void *)I80_HW_TRG
679	},
680	{
681		.compatible = "samsung,exynos5433-decon-tv",
682		.data = (void *)(I80_HW_TRG | IFTYPE_HDMI)
683	},
684	{},
685};
686MODULE_DEVICE_TABLE(of, exynos5433_decon_driver_dt_match);
687
688static int decon_conf_irq(struct decon_context *ctx, const char *name,
689		irq_handler_t handler, unsigned long int flags)
690{
691	struct platform_device *pdev = to_platform_device(ctx->dev);
692	int ret, irq = platform_get_irq_byname(pdev, name);
693
694	if (irq < 0) {
695		switch (irq) {
696		case -EPROBE_DEFER:
697			return irq;
698		case -ENODATA:
699		case -ENXIO:
700			return 0;
701		default:
702			dev_err(ctx->dev, "IRQ %s get failed, %d\n", name, irq);
703			return irq;
704		}
705	}
706	irq_set_status_flags(irq, IRQ_NOAUTOEN);
707	ret = devm_request_irq(ctx->dev, irq, handler, flags, "drm_decon", ctx);
708	if (ret < 0) {
709		dev_err(ctx->dev, "IRQ %s request failed\n", name);
710		return ret;
711	}
712
713	return irq;
714}
715
716static int exynos5433_decon_probe(struct platform_device *pdev)
717{
718	struct device *dev = &pdev->dev;
719	struct decon_context *ctx;
720	struct resource *res;
721	int ret;
722	int i;
723
724	ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
725	if (!ctx)
726		return -ENOMEM;
727
728	ctx->dev = dev;
729	ctx->out_type = (unsigned long)of_device_get_match_data(dev);
730	spin_lock_init(&ctx->vblank_lock);
731
732	if (ctx->out_type & IFTYPE_HDMI)
733		ctx->first_win = 1;
734
735	for (i = 0; i < ARRAY_SIZE(decon_clks_name); i++) {
736		struct clk *clk;
737
738		clk = devm_clk_get(ctx->dev, decon_clks_name[i]);
739		if (IS_ERR(clk))
740			return PTR_ERR(clk);
741
742		ctx->clks[i] = clk;
743	}
744
745	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
746	ctx->addr = devm_ioremap_resource(dev, res);
747	if (IS_ERR(ctx->addr)) {
748		dev_err(dev, "ioremap failed\n");
749		return PTR_ERR(ctx->addr);
750	}
751
752	ret = decon_conf_irq(ctx, "vsync", decon_irq_handler, 0);
753	if (ret < 0)
754		return ret;
755	ctx->irq_vsync = ret;
756
757	ret = decon_conf_irq(ctx, "lcd_sys", decon_irq_handler, 0);
758	if (ret < 0)
759		return ret;
760	ctx->irq_lcd_sys = ret;
761
762	ret = decon_conf_irq(ctx, "te", decon_te_irq_handler,
763			IRQF_TRIGGER_RISING);
764	if (ret < 0)
765			return ret;
766	if (ret) {
767		ctx->te_irq = ret;
768		ctx->out_type &= ~I80_HW_TRG;
769	}
770
771	if (ctx->out_type & I80_HW_TRG) {
772		ctx->sysreg = syscon_regmap_lookup_by_phandle(dev->of_node,
773							"samsung,disp-sysreg");
774		if (IS_ERR(ctx->sysreg)) {
775			dev_err(dev, "failed to get system register\n");
776			return PTR_ERR(ctx->sysreg);
777		}
778	}
779
780	platform_set_drvdata(pdev, ctx);
781
782	pm_runtime_enable(dev);
783
784	ret = component_add(dev, &decon_component_ops);
785	if (ret)
786		goto err_disable_pm_runtime;
787
788	return 0;
789
790err_disable_pm_runtime:
791	pm_runtime_disable(dev);
792
793	return ret;
794}
795
796static int exynos5433_decon_remove(struct platform_device *pdev)
797{
798	pm_runtime_disable(&pdev->dev);
799
800	component_del(&pdev->dev, &decon_component_ops);
801
802	return 0;
803}
804
805struct platform_driver exynos5433_decon_driver = {
806	.probe		= exynos5433_decon_probe,
807	.remove		= exynos5433_decon_remove,
808	.driver		= {
809		.name	= "exynos5433-decon",
810		.pm	= &exynos5433_decon_pm_ops,
811		.of_match_table = exynos5433_decon_driver_dt_match,
812	},
813};