1d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim/*
2d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim * Copyright (C) 2011 Samsung Electronics Co.Ltd
3d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim * Authors:
4d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim * Seung-Woo Kim <sw0312.kim@samsung.com>
5d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim *	Inki Dae <inki.dae@samsung.com>
6d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim *	Joonyoung Shim <jy0922.shim@samsung.com>
7d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim *
8d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim * Based on drivers/media/video/s5p-tv/mixer_reg.c
9d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim *
10d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim * This program is free software; you can redistribute  it and/or modify it
11d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim * under  the terms of  the GNU General  Public License as published by the
12d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim * Free Software Foundation;  either version 2 of the  License, or (at your
13d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim * option) any later version.
14d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim *
15d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim */
16d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
17d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim#include "drmP.h"
18d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
19d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim#include "regs-mixer.h"
20d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim#include "regs-vp.h"
21d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
22d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim#include <linux/kernel.h>
23d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim#include <linux/spinlock.h>
24d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim#include <linux/wait.h>
25d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim#include <linux/i2c.h>
26d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim#include <linux/module.h>
27d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim#include <linux/platform_device.h>
28d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim#include <linux/interrupt.h>
29d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim#include <linux/irq.h>
30d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim#include <linux/delay.h>
31d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim#include <linux/pm_runtime.h>
32d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim#include <linux/clk.h>
33d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim#include <linux/regulator/consumer.h>
34d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
35d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim#include <drm/exynos_drm.h>
36d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
37d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim#include "exynos_drm_drv.h"
38d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim#include "exynos_drm_hdmi.h"
3922b21ae6b84f7df62e77f05f58bb4360146c5414Joonyoung Shim
40a634dd54c05636a89a272e27e59118374065975eJoonyoung Shim#define MIXER_WIN_NR		3
41a2ee151b6b6863d108552de82e02b77166ca23a8Joonyoung Shim#define MIXER_DEFAULT_WIN	0
42d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
43d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim#define get_mixer_context(dev)	platform_get_drvdata(to_platform_device(dev))
44d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
4522b21ae6b84f7df62e77f05f58bb4360146c5414Joonyoung Shimstruct hdmi_win_data {
4622b21ae6b84f7df62e77f05f58bb4360146c5414Joonyoung Shim	dma_addr_t		dma_addr;
4722b21ae6b84f7df62e77f05f58bb4360146c5414Joonyoung Shim	void __iomem		*vaddr;
4822b21ae6b84f7df62e77f05f58bb4360146c5414Joonyoung Shim	dma_addr_t		chroma_dma_addr;
4922b21ae6b84f7df62e77f05f58bb4360146c5414Joonyoung Shim	void __iomem		*chroma_vaddr;
5022b21ae6b84f7df62e77f05f58bb4360146c5414Joonyoung Shim	uint32_t		pixel_format;
5122b21ae6b84f7df62e77f05f58bb4360146c5414Joonyoung Shim	unsigned int		bpp;
5222b21ae6b84f7df62e77f05f58bb4360146c5414Joonyoung Shim	unsigned int		crtc_x;
5322b21ae6b84f7df62e77f05f58bb4360146c5414Joonyoung Shim	unsigned int		crtc_y;
5422b21ae6b84f7df62e77f05f58bb4360146c5414Joonyoung Shim	unsigned int		crtc_width;
5522b21ae6b84f7df62e77f05f58bb4360146c5414Joonyoung Shim	unsigned int		crtc_height;
5622b21ae6b84f7df62e77f05f58bb4360146c5414Joonyoung Shim	unsigned int		fb_x;
5722b21ae6b84f7df62e77f05f58bb4360146c5414Joonyoung Shim	unsigned int		fb_y;
5822b21ae6b84f7df62e77f05f58bb4360146c5414Joonyoung Shim	unsigned int		fb_width;
5922b21ae6b84f7df62e77f05f58bb4360146c5414Joonyoung Shim	unsigned int		fb_height;
6022b21ae6b84f7df62e77f05f58bb4360146c5414Joonyoung Shim	unsigned int		mode_width;
6122b21ae6b84f7df62e77f05f58bb4360146c5414Joonyoung Shim	unsigned int		mode_height;
6222b21ae6b84f7df62e77f05f58bb4360146c5414Joonyoung Shim	unsigned int		scan_flags;
6322b21ae6b84f7df62e77f05f58bb4360146c5414Joonyoung Shim};
6422b21ae6b84f7df62e77f05f58bb4360146c5414Joonyoung Shim
6522b21ae6b84f7df62e77f05f58bb4360146c5414Joonyoung Shimstruct mixer_resources {
6622b21ae6b84f7df62e77f05f58bb4360146c5414Joonyoung Shim	struct device		*dev;
6722b21ae6b84f7df62e77f05f58bb4360146c5414Joonyoung Shim	int			irq;
6822b21ae6b84f7df62e77f05f58bb4360146c5414Joonyoung Shim	void __iomem		*mixer_regs;
6922b21ae6b84f7df62e77f05f58bb4360146c5414Joonyoung Shim	void __iomem		*vp_regs;
7022b21ae6b84f7df62e77f05f58bb4360146c5414Joonyoung Shim	spinlock_t		reg_slock;
7122b21ae6b84f7df62e77f05f58bb4360146c5414Joonyoung Shim	struct clk		*mixer;
7222b21ae6b84f7df62e77f05f58bb4360146c5414Joonyoung Shim	struct clk		*vp;
7322b21ae6b84f7df62e77f05f58bb4360146c5414Joonyoung Shim	struct clk		*sclk_mixer;
7422b21ae6b84f7df62e77f05f58bb4360146c5414Joonyoung Shim	struct clk		*sclk_hdmi;
7522b21ae6b84f7df62e77f05f58bb4360146c5414Joonyoung Shim	struct clk		*sclk_dac;
7622b21ae6b84f7df62e77f05f58bb4360146c5414Joonyoung Shim};
7722b21ae6b84f7df62e77f05f58bb4360146c5414Joonyoung Shim
7822b21ae6b84f7df62e77f05f58bb4360146c5414Joonyoung Shimstruct mixer_context {
7922b21ae6b84f7df62e77f05f58bb4360146c5414Joonyoung Shim	unsigned int		irq;
8022b21ae6b84f7df62e77f05f58bb4360146c5414Joonyoung Shim	int			pipe;
8122b21ae6b84f7df62e77f05f58bb4360146c5414Joonyoung Shim	bool			interlace;
8222b21ae6b84f7df62e77f05f58bb4360146c5414Joonyoung Shim
8322b21ae6b84f7df62e77f05f58bb4360146c5414Joonyoung Shim	struct mixer_resources	mixer_res;
84a634dd54c05636a89a272e27e59118374065975eJoonyoung Shim	struct hdmi_win_data	win_data[MIXER_WIN_NR];
8522b21ae6b84f7df62e77f05f58bb4360146c5414Joonyoung Shim};
8622b21ae6b84f7df62e77f05f58bb4360146c5414Joonyoung Shim
87d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kimstatic const u8 filter_y_horiz_tap8[] = {
88d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	0,	-1,	-1,	-1,	-1,	-1,	-1,	-1,
89d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	-1,	-1,	-1,	-1,	-1,	0,	0,	0,
90d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	0,	2,	4,	5,	6,	6,	6,	6,
91d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	6,	5,	5,	4,	3,	2,	1,	1,
92d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	0,	-6,	-12,	-16,	-18,	-20,	-21,	-20,
93d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	-20,	-18,	-16,	-13,	-10,	-8,	-5,	-2,
94d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	127,	126,	125,	121,	114,	107,	99,	89,
95d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	79,	68,	57,	46,	35,	25,	16,	8,
96d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim};
97d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
98d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kimstatic const u8 filter_y_vert_tap4[] = {
99d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	0,	-3,	-6,	-8,	-8,	-8,	-8,	-7,
100d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	-6,	-5,	-4,	-3,	-2,	-1,	-1,	0,
101d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	127,	126,	124,	118,	111,	102,	92,	81,
102d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	70,	59,	48,	37,	27,	19,	11,	5,
103d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	0,	5,	11,	19,	27,	37,	48,	59,
104d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	70,	81,	92,	102,	111,	118,	124,	126,
105d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	0,	0,	-1,	-1,	-2,	-3,	-4,	-5,
106d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	-6,	-7,	-8,	-8,	-8,	-8,	-6,	-3,
107d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim};
108d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
109d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kimstatic const u8 filter_cr_horiz_tap4[] = {
110d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	0,	-3,	-6,	-8,	-8,	-8,	-8,	-7,
111d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	-6,	-5,	-4,	-3,	-2,	-1,	-1,	0,
112d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	127,	126,	124,	118,	111,	102,	92,	81,
113d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	70,	59,	48,	37,	27,	19,	11,	5,
114d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim};
115d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
116d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kimstatic inline u32 vp_reg_read(struct mixer_resources *res, u32 reg_id)
117d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim{
118d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	return readl(res->vp_regs + reg_id);
119d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim}
120d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
121d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kimstatic inline void vp_reg_write(struct mixer_resources *res, u32 reg_id,
122d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim				 u32 val)
123d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim{
124d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	writel(val, res->vp_regs + reg_id);
125d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim}
126d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
127d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kimstatic inline void vp_reg_writemask(struct mixer_resources *res, u32 reg_id,
128d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim				 u32 val, u32 mask)
129d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim{
130d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	u32 old = vp_reg_read(res, reg_id);
131d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
132d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	val = (val & mask) | (old & ~mask);
133d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	writel(val, res->vp_regs + reg_id);
134d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim}
135d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
136d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kimstatic inline u32 mixer_reg_read(struct mixer_resources *res, u32 reg_id)
137d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim{
138d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	return readl(res->mixer_regs + reg_id);
139d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim}
140d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
141d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kimstatic inline void mixer_reg_write(struct mixer_resources *res, u32 reg_id,
142d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim				 u32 val)
143d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim{
144d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	writel(val, res->mixer_regs + reg_id);
145d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim}
146d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
147d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kimstatic inline void mixer_reg_writemask(struct mixer_resources *res,
148d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim				 u32 reg_id, u32 val, u32 mask)
149d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim{
150d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	u32 old = mixer_reg_read(res, reg_id);
151d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
152d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	val = (val & mask) | (old & ~mask);
153d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	writel(val, res->mixer_regs + reg_id);
154d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim}
155d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
156d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kimstatic void mixer_regs_dump(struct mixer_context *ctx)
157d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim{
158d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim#define DUMPREG(reg_id) \
159d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kimdo { \
160d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	DRM_DEBUG_KMS(#reg_id " = %08x\n", \
161d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		(u32)readl(ctx->mixer_res.mixer_regs + reg_id)); \
162d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim} while (0)
163d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
164d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	DUMPREG(MXR_STATUS);
165d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	DUMPREG(MXR_CFG);
166d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	DUMPREG(MXR_INT_EN);
167d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	DUMPREG(MXR_INT_STATUS);
168d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
169d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	DUMPREG(MXR_LAYER_CFG);
170d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	DUMPREG(MXR_VIDEO_CFG);
171d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
172d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	DUMPREG(MXR_GRAPHIC0_CFG);
173d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	DUMPREG(MXR_GRAPHIC0_BASE);
174d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	DUMPREG(MXR_GRAPHIC0_SPAN);
175d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	DUMPREG(MXR_GRAPHIC0_WH);
176d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	DUMPREG(MXR_GRAPHIC0_SXY);
177d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	DUMPREG(MXR_GRAPHIC0_DXY);
178d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
179d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	DUMPREG(MXR_GRAPHIC1_CFG);
180d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	DUMPREG(MXR_GRAPHIC1_BASE);
181d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	DUMPREG(MXR_GRAPHIC1_SPAN);
182d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	DUMPREG(MXR_GRAPHIC1_WH);
183d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	DUMPREG(MXR_GRAPHIC1_SXY);
184d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	DUMPREG(MXR_GRAPHIC1_DXY);
185d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim#undef DUMPREG
186d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim}
187d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
188d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kimstatic void vp_regs_dump(struct mixer_context *ctx)
189d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim{
190d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim#define DUMPREG(reg_id) \
191d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kimdo { \
192d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	DRM_DEBUG_KMS(#reg_id " = %08x\n", \
193d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		(u32) readl(ctx->mixer_res.vp_regs + reg_id)); \
194d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim} while (0)
195d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
196d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	DUMPREG(VP_ENABLE);
197d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	DUMPREG(VP_SRESET);
198d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	DUMPREG(VP_SHADOW_UPDATE);
199d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	DUMPREG(VP_FIELD_ID);
200d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	DUMPREG(VP_MODE);
201d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	DUMPREG(VP_IMG_SIZE_Y);
202d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	DUMPREG(VP_IMG_SIZE_C);
203d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	DUMPREG(VP_PER_RATE_CTRL);
204d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	DUMPREG(VP_TOP_Y_PTR);
205d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	DUMPREG(VP_BOT_Y_PTR);
206d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	DUMPREG(VP_TOP_C_PTR);
207d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	DUMPREG(VP_BOT_C_PTR);
208d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	DUMPREG(VP_ENDIAN_MODE);
209d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	DUMPREG(VP_SRC_H_POSITION);
210d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	DUMPREG(VP_SRC_V_POSITION);
211d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	DUMPREG(VP_SRC_WIDTH);
212d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	DUMPREG(VP_SRC_HEIGHT);
213d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	DUMPREG(VP_DST_H_POSITION);
214d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	DUMPREG(VP_DST_V_POSITION);
215d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	DUMPREG(VP_DST_WIDTH);
216d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	DUMPREG(VP_DST_HEIGHT);
217d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	DUMPREG(VP_H_RATIO);
218d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	DUMPREG(VP_V_RATIO);
219d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
220d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim#undef DUMPREG
221d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim}
222d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
223d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kimstatic inline void vp_filter_set(struct mixer_resources *res,
224d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		int reg_id, const u8 *data, unsigned int size)
225d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim{
226d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	/* assure 4-byte align */
227d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	BUG_ON(size & 3);
228d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	for (; size; size -= 4, reg_id += 4, data += 4) {
229d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		u32 val = (data[0] << 24) |  (data[1] << 16) |
230d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim			(data[2] << 8) | data[3];
231d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		vp_reg_write(res, reg_id, val);
232d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	}
233d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim}
234d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
235d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kimstatic void vp_default_filter(struct mixer_resources *res)
236d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim{
237d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	vp_filter_set(res, VP_POLY8_Y0_LL,
238d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		filter_y_horiz_tap8, sizeof filter_y_horiz_tap8);
239d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	vp_filter_set(res, VP_POLY4_Y0_LL,
240d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		filter_y_vert_tap4, sizeof filter_y_vert_tap4);
241d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	vp_filter_set(res, VP_POLY4_C0_LL,
242d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		filter_cr_horiz_tap4, sizeof filter_cr_horiz_tap4);
243d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim}
244d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
245d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kimstatic void mixer_vsync_set_update(struct mixer_context *ctx, bool enable)
246d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim{
247d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	struct mixer_resources *res = &ctx->mixer_res;
248d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
249d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	/* block update on vsync */
250d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	mixer_reg_writemask(res, MXR_STATUS, enable ?
251d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim			MXR_STATUS_SYNC_ENABLE : 0, MXR_STATUS_SYNC_ENABLE);
252d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
253d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	vp_reg_write(res, VP_SHADOW_UPDATE, enable ?
254d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim			VP_SHADOW_UPDATE_ENABLE : 0);
255d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim}
256d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
257d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kimstatic void mixer_cfg_scan(struct mixer_context *ctx, unsigned int height)
258d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim{
259d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	struct mixer_resources *res = &ctx->mixer_res;
260d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	u32 val;
261d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
262d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	/* choosing between interlace and progressive mode */
263d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	val = (ctx->interlace ? MXR_CFG_SCAN_INTERLACE :
264d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim				MXR_CFG_SCAN_PROGRASSIVE);
265d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
266d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	/* choosing between porper HD and SD mode */
267d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	if (height == 480)
268d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		val |= MXR_CFG_SCAN_NTSC | MXR_CFG_SCAN_SD;
269d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	else if (height == 576)
270d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		val |= MXR_CFG_SCAN_PAL | MXR_CFG_SCAN_SD;
271d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	else if (height == 720)
272d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		val |= MXR_CFG_SCAN_HD_720 | MXR_CFG_SCAN_HD;
273d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	else if (height == 1080)
274d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		val |= MXR_CFG_SCAN_HD_1080 | MXR_CFG_SCAN_HD;
275d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	else
276d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		val |= MXR_CFG_SCAN_HD_720 | MXR_CFG_SCAN_HD;
277d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
278d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	mixer_reg_writemask(res, MXR_CFG, val, MXR_CFG_SCAN_MASK);
279d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim}
280d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
281d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kimstatic void mixer_cfg_rgb_fmt(struct mixer_context *ctx, unsigned int height)
282d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim{
283d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	struct mixer_resources *res = &ctx->mixer_res;
284d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	u32 val;
285d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
286d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	if (height == 480) {
287d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		val = MXR_CFG_RGB601_0_255;
288d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	} else if (height == 576) {
289d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		val = MXR_CFG_RGB601_0_255;
290d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	} else if (height == 720) {
291d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		val = MXR_CFG_RGB709_16_235;
292d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		mixer_reg_write(res, MXR_CM_COEFF_Y,
293d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim				(1 << 30) | (94 << 20) | (314 << 10) |
294d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim				(32 << 0));
295d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		mixer_reg_write(res, MXR_CM_COEFF_CB,
296d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim				(972 << 20) | (851 << 10) | (225 << 0));
297d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		mixer_reg_write(res, MXR_CM_COEFF_CR,
298d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim				(225 << 20) | (820 << 10) | (1004 << 0));
299d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	} else if (height == 1080) {
300d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		val = MXR_CFG_RGB709_16_235;
301d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		mixer_reg_write(res, MXR_CM_COEFF_Y,
302d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim				(1 << 30) | (94 << 20) | (314 << 10) |
303d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim				(32 << 0));
304d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		mixer_reg_write(res, MXR_CM_COEFF_CB,
305d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim				(972 << 20) | (851 << 10) | (225 << 0));
306d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		mixer_reg_write(res, MXR_CM_COEFF_CR,
307d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim				(225 << 20) | (820 << 10) | (1004 << 0));
308d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	} else {
309d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		val = MXR_CFG_RGB709_16_235;
310d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		mixer_reg_write(res, MXR_CM_COEFF_Y,
311d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim				(1 << 30) | (94 << 20) | (314 << 10) |
312d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim				(32 << 0));
313d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		mixer_reg_write(res, MXR_CM_COEFF_CB,
314d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim				(972 << 20) | (851 << 10) | (225 << 0));
315d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		mixer_reg_write(res, MXR_CM_COEFF_CR,
316d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim				(225 << 20) | (820 << 10) | (1004 << 0));
317d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	}
318d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
319d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	mixer_reg_writemask(res, MXR_CFG, val, MXR_CFG_RGB_FMT_MASK);
320d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim}
321d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
322d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kimstatic void mixer_cfg_layer(struct mixer_context *ctx, int win, bool enable)
323d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim{
324d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	struct mixer_resources *res = &ctx->mixer_res;
325d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	u32 val = enable ? ~0 : 0;
326d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
327d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	switch (win) {
328d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	case 0:
329d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		mixer_reg_writemask(res, MXR_CFG, val, MXR_CFG_GRP0_ENABLE);
330d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		break;
331d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	case 1:
332d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		mixer_reg_writemask(res, MXR_CFG, val, MXR_CFG_GRP1_ENABLE);
333d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		break;
334d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	case 2:
335d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		vp_reg_writemask(res, VP_ENABLE, val, VP_ENABLE_ON);
336d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		mixer_reg_writemask(res, MXR_CFG, val, MXR_CFG_VP_ENABLE);
337d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		break;
338d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	}
339d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim}
340d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
341d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kimstatic void mixer_run(struct mixer_context *ctx)
342d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim{
343d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	struct mixer_resources *res = &ctx->mixer_res;
344d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
345d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	mixer_reg_writemask(res, MXR_STATUS, ~0, MXR_STATUS_REG_RUN);
346d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
347d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	mixer_regs_dump(ctx);
348d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim}
349d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
350d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kimstatic void vp_video_buffer(struct mixer_context *ctx, int win)
351d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim{
352d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	struct mixer_resources *res = &ctx->mixer_res;
353d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	unsigned long flags;
354d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	struct hdmi_win_data *win_data;
355d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	unsigned int full_width, full_height, width, height;
356d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	unsigned int x_ratio, y_ratio;
357d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	unsigned int src_x_offset, src_y_offset, dst_x_offset, dst_y_offset;
358d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	unsigned int mode_width, mode_height;
359d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	unsigned int buf_num;
360d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	dma_addr_t luma_addr[2], chroma_addr[2];
361d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	bool tiled_mode = false;
362d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	bool crcb_mode = false;
363d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	u32 val;
364d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
365d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	win_data = &ctx->win_data[win];
366d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
367d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	switch (win_data->pixel_format) {
368d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	case DRM_FORMAT_NV12MT:
369d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		tiled_mode = true;
370d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	case DRM_FORMAT_NV12M:
371d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		crcb_mode = false;
372d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		buf_num = 2;
373d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		break;
374d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	/* TODO: single buffer format NV12, NV21 */
375d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	default:
376d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		/* ignore pixel format at disable time */
377d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		if (!win_data->dma_addr)
378d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim			break;
379d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
380d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		DRM_ERROR("pixel format for vp is wrong [%d].\n",
381d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim				win_data->pixel_format);
382d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		return;
383d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	}
384d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
385d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	full_width = win_data->fb_width;
386d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	full_height = win_data->fb_height;
387d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	width = win_data->crtc_width;
388d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	height = win_data->crtc_height;
389d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	mode_width = win_data->mode_width;
390d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	mode_height = win_data->mode_height;
391d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
392d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	/* scaling feature: (src << 16) / dst */
393d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	x_ratio = (width << 16) / width;
394d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	y_ratio = (height << 16) / height;
395d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
396d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	src_x_offset = win_data->fb_x;
397d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	src_y_offset = win_data->fb_y;
398d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	dst_x_offset = win_data->crtc_x;
399d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	dst_y_offset = win_data->crtc_y;
400d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
401d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	if (buf_num == 2) {
402d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		luma_addr[0] = win_data->dma_addr;
403d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		chroma_addr[0] = win_data->chroma_dma_addr;
404d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	} else {
405d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		luma_addr[0] = win_data->dma_addr;
406d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		chroma_addr[0] = win_data->dma_addr
407d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim			+ (full_width * full_height);
408d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	}
409d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
410d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	if (win_data->scan_flags & DRM_MODE_FLAG_INTERLACE) {
411d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		ctx->interlace = true;
412d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		if (tiled_mode) {
413d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim			luma_addr[1] = luma_addr[0] + 0x40;
414d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim			chroma_addr[1] = chroma_addr[0] + 0x40;
415d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		} else {
416d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim			luma_addr[1] = luma_addr[0] + full_width;
417d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim			chroma_addr[1] = chroma_addr[0] + full_width;
418d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		}
419d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	} else {
420d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		ctx->interlace = false;
421d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		luma_addr[1] = 0;
422d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		chroma_addr[1] = 0;
423d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	}
424d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
425d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	spin_lock_irqsave(&res->reg_slock, flags);
426d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	mixer_vsync_set_update(ctx, false);
427d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
428d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	/* interlace or progressive scan mode */
429d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	val = (ctx->interlace ? ~0 : 0);
430d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	vp_reg_writemask(res, VP_MODE, val, VP_MODE_LINE_SKIP);
431d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
432d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	/* setup format */
433d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	val = (crcb_mode ? VP_MODE_NV21 : VP_MODE_NV12);
434d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	val |= (tiled_mode ? VP_MODE_MEM_TILED : VP_MODE_MEM_LINEAR);
435d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	vp_reg_writemask(res, VP_MODE, val, VP_MODE_FMT_MASK);
436d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
437d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	/* setting size of input image */
438d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	vp_reg_write(res, VP_IMG_SIZE_Y, VP_IMG_HSIZE(full_width) |
439d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		VP_IMG_VSIZE(full_height));
440d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	/* chroma height has to reduced by 2 to avoid chroma distorions */
441d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	vp_reg_write(res, VP_IMG_SIZE_C, VP_IMG_HSIZE(full_width) |
442d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		VP_IMG_VSIZE(full_height / 2));
443d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
444d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	vp_reg_write(res, VP_SRC_WIDTH, width);
445d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	vp_reg_write(res, VP_SRC_HEIGHT, height);
446d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	vp_reg_write(res, VP_SRC_H_POSITION,
447d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim			VP_SRC_H_POSITION_VAL(src_x_offset));
448d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	vp_reg_write(res, VP_SRC_V_POSITION, src_y_offset);
449d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
450d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	vp_reg_write(res, VP_DST_WIDTH, width);
451d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	vp_reg_write(res, VP_DST_H_POSITION, dst_x_offset);
452d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	if (ctx->interlace) {
453d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		vp_reg_write(res, VP_DST_HEIGHT, height / 2);
454d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		vp_reg_write(res, VP_DST_V_POSITION, dst_y_offset / 2);
455d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	} else {
456d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		vp_reg_write(res, VP_DST_HEIGHT, height);
457d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		vp_reg_write(res, VP_DST_V_POSITION, dst_y_offset);
458d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	}
459d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
460d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	vp_reg_write(res, VP_H_RATIO, x_ratio);
461d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	vp_reg_write(res, VP_V_RATIO, y_ratio);
462d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
463d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	vp_reg_write(res, VP_ENDIAN_MODE, VP_ENDIAN_MODE_LITTLE);
464d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
465d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	/* set buffer address to vp */
466d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	vp_reg_write(res, VP_TOP_Y_PTR, luma_addr[0]);
467d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	vp_reg_write(res, VP_BOT_Y_PTR, luma_addr[1]);
468d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	vp_reg_write(res, VP_TOP_C_PTR, chroma_addr[0]);
469d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	vp_reg_write(res, VP_BOT_C_PTR, chroma_addr[1]);
470d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
471d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	mixer_cfg_scan(ctx, mode_height);
472d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	mixer_cfg_rgb_fmt(ctx, mode_height);
473d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	mixer_cfg_layer(ctx, win, true);
474d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	mixer_run(ctx);
475d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
476d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	mixer_vsync_set_update(ctx, true);
477d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	spin_unlock_irqrestore(&res->reg_slock, flags);
478d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
479d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	vp_regs_dump(ctx);
480d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim}
481d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
482d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kimstatic void mixer_graph_buffer(struct mixer_context *ctx, int win)
483d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim{
484d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	struct mixer_resources *res = &ctx->mixer_res;
485d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	unsigned long flags;
486d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	struct hdmi_win_data *win_data;
487d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	unsigned int full_width, width, height;
488d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	unsigned int x_ratio, y_ratio;
489d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	unsigned int src_x_offset, src_y_offset, dst_x_offset, dst_y_offset;
490d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	unsigned int mode_width, mode_height;
491d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	dma_addr_t dma_addr;
492d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	unsigned int fmt;
493d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	u32 val;
494d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
495d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	win_data = &ctx->win_data[win];
496d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
497d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	#define RGB565 4
498d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	#define ARGB1555 5
499d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	#define ARGB4444 6
500d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	#define ARGB8888 7
501d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
502d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	switch (win_data->bpp) {
503d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	case 16:
504d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		fmt = ARGB4444;
505d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		break;
506d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	case 32:
507d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		fmt = ARGB8888;
508d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		break;
509d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	default:
510d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		fmt = ARGB8888;
511d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	}
512d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
513d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	dma_addr = win_data->dma_addr;
514d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	full_width = win_data->fb_width;
515d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	width = win_data->crtc_width;
516d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	height = win_data->crtc_height;
517d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	mode_width = win_data->mode_width;
518d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	mode_height = win_data->mode_height;
519d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
520d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	/* 2x scaling feature */
521d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	x_ratio = 0;
522d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	y_ratio = 0;
523d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
524d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	src_x_offset = win_data->fb_x;
525d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	src_y_offset = win_data->fb_y;
526d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	dst_x_offset = win_data->crtc_x;
527d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	dst_y_offset = win_data->crtc_y;
528d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
529d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	/* converting dma address base and source offset */
530d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	dma_addr = dma_addr
531d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		+ (src_x_offset * win_data->bpp >> 3)
532d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		+ (src_y_offset * full_width * win_data->bpp >> 3);
533d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	src_x_offset = 0;
534d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	src_y_offset = 0;
535d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
536d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	if (win_data->scan_flags & DRM_MODE_FLAG_INTERLACE)
537d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		ctx->interlace = true;
538d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	else
539d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		ctx->interlace = false;
540d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
541d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	spin_lock_irqsave(&res->reg_slock, flags);
542d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	mixer_vsync_set_update(ctx, false);
543d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
544d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	/* setup format */
545d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	mixer_reg_writemask(res, MXR_GRAPHIC_CFG(win),
546d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		MXR_GRP_CFG_FORMAT_VAL(fmt), MXR_GRP_CFG_FORMAT_MASK);
547d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
548d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	/* setup geometry */
549d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	mixer_reg_write(res, MXR_GRAPHIC_SPAN(win), full_width);
550d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
551d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	val  = MXR_GRP_WH_WIDTH(width);
552d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	val |= MXR_GRP_WH_HEIGHT(height);
553d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	val |= MXR_GRP_WH_H_SCALE(x_ratio);
554d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	val |= MXR_GRP_WH_V_SCALE(y_ratio);
555d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	mixer_reg_write(res, MXR_GRAPHIC_WH(win), val);
556d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
557d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	/* setup offsets in source image */
558d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	val  = MXR_GRP_SXY_SX(src_x_offset);
559d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	val |= MXR_GRP_SXY_SY(src_y_offset);
560d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	mixer_reg_write(res, MXR_GRAPHIC_SXY(win), val);
561d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
562d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	/* setup offsets in display image */
563d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	val  = MXR_GRP_DXY_DX(dst_x_offset);
564d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	val |= MXR_GRP_DXY_DY(dst_y_offset);
565d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	mixer_reg_write(res, MXR_GRAPHIC_DXY(win), val);
566d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
567d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	/* set buffer address to mixer */
568d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	mixer_reg_write(res, MXR_GRAPHIC_BASE(win), dma_addr);
569d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
570d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	mixer_cfg_scan(ctx, mode_height);
571d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	mixer_cfg_rgb_fmt(ctx, mode_height);
572d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	mixer_cfg_layer(ctx, win, true);
573d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	mixer_run(ctx);
574d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
575d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	mixer_vsync_set_update(ctx, true);
576d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	spin_unlock_irqrestore(&res->reg_slock, flags);
577d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim}
578d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
579d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kimstatic void vp_win_reset(struct mixer_context *ctx)
580d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim{
581d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	struct mixer_resources *res = &ctx->mixer_res;
582d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	int tries = 100;
583d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
584d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	vp_reg_write(res, VP_SRESET, VP_SRESET_PROCESSING);
585d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	for (tries = 100; tries; --tries) {
586d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		/* waiting until VP_SRESET_PROCESSING is 0 */
587d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		if (~vp_reg_read(res, VP_SRESET) & VP_SRESET_PROCESSING)
588d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim			break;
589d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		mdelay(10);
590d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	}
591d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	WARN(tries == 0, "failed to reset Video Processor\n");
592d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim}
593d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
594d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kimstatic int mixer_enable_vblank(void *ctx, int pipe)
595d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim{
596d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	struct mixer_context *mixer_ctx = ctx;
597d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	struct mixer_resources *res = &mixer_ctx->mixer_res;
598d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
599d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
600d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
601d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	mixer_ctx->pipe = pipe;
602d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
603d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	/* enable vsync interrupt */
604d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	mixer_reg_writemask(res, MXR_INT_EN, MXR_INT_EN_VSYNC,
605d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim			MXR_INT_EN_VSYNC);
606d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
607d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	return 0;
608d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim}
609d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
610d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kimstatic void mixer_disable_vblank(void *ctx)
611d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim{
612d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	struct mixer_context *mixer_ctx = ctx;
613d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	struct mixer_resources *res = &mixer_ctx->mixer_res;
614d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
615d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
616d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
617d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	/* disable vsync interrupt */
618d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	mixer_reg_writemask(res, MXR_INT_EN, 0, MXR_INT_EN_VSYNC);
619d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim}
620d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
621d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kimstatic void mixer_win_mode_set(void *ctx,
622d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim			      struct exynos_drm_overlay *overlay)
623d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim{
624d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	struct mixer_context *mixer_ctx = ctx;
625d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	struct hdmi_win_data *win_data;
626d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	int win;
627d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
628d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
629d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
630d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	if (!overlay) {
631d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		DRM_ERROR("overlay is NULL\n");
632d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		return;
633d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	}
634d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
635d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	DRM_DEBUG_KMS("set [%d]x[%d] at (%d,%d) to [%d]x[%d] at (%d,%d)\n",
636d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim				 overlay->fb_width, overlay->fb_height,
637d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim				 overlay->fb_x, overlay->fb_y,
638d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim				 overlay->crtc_width, overlay->crtc_height,
639d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim				 overlay->crtc_x, overlay->crtc_y);
640d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
641d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	win = overlay->zpos;
642d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	if (win == DEFAULT_ZPOS)
643a2ee151b6b6863d108552de82e02b77166ca23a8Joonyoung Shim		win = MIXER_DEFAULT_WIN;
644d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
645a634dd54c05636a89a272e27e59118374065975eJoonyoung Shim	if (win < 0 || win > MIXER_WIN_NR) {
646d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		DRM_ERROR("overlay plane[%d] is wrong\n", win);
647d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		return;
648d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	}
649d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
650d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	win_data = &mixer_ctx->win_data[win];
651d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
652d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	win_data->dma_addr = overlay->dma_addr[0];
653d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	win_data->vaddr = overlay->vaddr[0];
654d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	win_data->chroma_dma_addr = overlay->dma_addr[1];
655d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	win_data->chroma_vaddr = overlay->vaddr[1];
656d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	win_data->pixel_format = overlay->pixel_format;
657d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	win_data->bpp = overlay->bpp;
658d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
659d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	win_data->crtc_x = overlay->crtc_x;
660d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	win_data->crtc_y = overlay->crtc_y;
661d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	win_data->crtc_width = overlay->crtc_width;
662d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	win_data->crtc_height = overlay->crtc_height;
663d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
664d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	win_data->fb_x = overlay->fb_x;
665d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	win_data->fb_y = overlay->fb_y;
666d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	win_data->fb_width = overlay->fb_width;
667d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	win_data->fb_height = overlay->fb_height;
668d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
669d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	win_data->mode_width = overlay->mode_width;
670d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	win_data->mode_height = overlay->mode_height;
671d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
672d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	win_data->scan_flags = overlay->scan_flag;
673d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim}
674d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
675d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kimstatic void mixer_win_commit(void *ctx, int zpos)
676d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim{
677d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	struct mixer_context *mixer_ctx = ctx;
678d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	int win = zpos;
679d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
680d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	DRM_DEBUG_KMS("[%d] %s, win: %d\n", __LINE__, __func__, win);
681d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
682d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	if (win == DEFAULT_ZPOS)
683a2ee151b6b6863d108552de82e02b77166ca23a8Joonyoung Shim		win = MIXER_DEFAULT_WIN;
684d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
685a634dd54c05636a89a272e27e59118374065975eJoonyoung Shim	if (win < 0 || win > MIXER_WIN_NR) {
686d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		DRM_ERROR("overlay plane[%d] is wrong\n", win);
687d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		return;
688d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	}
689d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
690d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	if (win > 1)
691d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		vp_video_buffer(mixer_ctx, win);
692d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	else
693d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		mixer_graph_buffer(mixer_ctx, win);
694d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim}
695d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
696d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kimstatic void mixer_win_disable(void *ctx, int zpos)
697d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim{
698d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	struct mixer_context *mixer_ctx = ctx;
699d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	struct mixer_resources *res = &mixer_ctx->mixer_res;
700d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	unsigned long flags;
701d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	int win = zpos;
702d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
703d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	DRM_DEBUG_KMS("[%d] %s, win: %d\n", __LINE__, __func__, win);
704d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
705d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	if (win == DEFAULT_ZPOS)
706a2ee151b6b6863d108552de82e02b77166ca23a8Joonyoung Shim		win = MIXER_DEFAULT_WIN;
707d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
708a634dd54c05636a89a272e27e59118374065975eJoonyoung Shim	if (win < 0 || win > MIXER_WIN_NR) {
709d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		DRM_ERROR("overlay plane[%d] is wrong\n", win);
710d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		return;
711d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	}
712d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
713d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	spin_lock_irqsave(&res->reg_slock, flags);
714d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	mixer_vsync_set_update(mixer_ctx, false);
715d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
716d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	mixer_cfg_layer(mixer_ctx, win, false);
717d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
718d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	mixer_vsync_set_update(mixer_ctx, true);
719d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	spin_unlock_irqrestore(&res->reg_slock, flags);
720d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim}
721d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
722578b6065adc8805a8774e4bf3145e18de123f8b2Joonyoung Shimstatic struct exynos_mixer_ops mixer_ops = {
723578b6065adc8805a8774e4bf3145e18de123f8b2Joonyoung Shim	/* manager */
724d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	.enable_vblank		= mixer_enable_vblank,
725d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	.disable_vblank		= mixer_disable_vblank,
726578b6065adc8805a8774e4bf3145e18de123f8b2Joonyoung Shim
727578b6065adc8805a8774e4bf3145e18de123f8b2Joonyoung Shim	/* overlay */
728d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	.win_mode_set		= mixer_win_mode_set,
729d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	.win_commit		= mixer_win_commit,
730d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	.win_disable		= mixer_win_disable,
731d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim};
732d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
733d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim/* for pageflip event */
734d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kimstatic void mixer_finish_pageflip(struct drm_device *drm_dev, int crtc)
735d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim{
736d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	struct exynos_drm_private *dev_priv = drm_dev->dev_private;
737d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	struct drm_pending_vblank_event *e, *t;
738d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	struct timeval now;
739d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	unsigned long flags;
740d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	bool is_checked = false;
741d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
742d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	spin_lock_irqsave(&drm_dev->event_lock, flags);
743d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
744d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	list_for_each_entry_safe(e, t, &dev_priv->pageflip_event_list,
745d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim			base.link) {
746d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		/* if event's pipe isn't same as crtc then ignore it. */
747d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		if (crtc != e->pipe)
748d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim			continue;
749d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
750d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		is_checked = true;
751d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		do_gettimeofday(&now);
752d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		e->event.sequence = 0;
753d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		e->event.tv_sec = now.tv_sec;
754d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		e->event.tv_usec = now.tv_usec;
755d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
756d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		list_move_tail(&e->base.link, &e->base.file_priv->event_list);
757d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		wake_up_interruptible(&e->base.file_priv->event_wait);
758d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	}
759d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
760d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	if (is_checked)
761c5614ae326c7fdd244d8e0365b8b78d5e3cd5bf4Inki Dae		/*
762c5614ae326c7fdd244d8e0365b8b78d5e3cd5bf4Inki Dae		 * call drm_vblank_put only in case that drm_vblank_get was
763c5614ae326c7fdd244d8e0365b8b78d5e3cd5bf4Inki Dae		 * called.
764c5614ae326c7fdd244d8e0365b8b78d5e3cd5bf4Inki Dae		 */
765c5614ae326c7fdd244d8e0365b8b78d5e3cd5bf4Inki Dae		if (atomic_read(&drm_dev->vblank_refcount[crtc]) > 0)
766c5614ae326c7fdd244d8e0365b8b78d5e3cd5bf4Inki Dae			drm_vblank_put(drm_dev, crtc);
767d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
768d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	spin_unlock_irqrestore(&drm_dev->event_lock, flags);
769d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim}
770d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
771d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kimstatic irqreturn_t mixer_irq_handler(int irq, void *arg)
772d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim{
773d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	struct exynos_drm_hdmi_context *drm_hdmi_ctx = arg;
774f9309d1bf220122659328040db47eede32514656Joonyoung Shim	struct mixer_context *ctx = drm_hdmi_ctx->ctx;
775d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	struct mixer_resources *res = &ctx->mixer_res;
776d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	u32 val, val_base;
777d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
778d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	spin_lock(&res->reg_slock);
779d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
780d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	/* read interrupt status for handling and clearing flags for VSYNC */
781d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	val = mixer_reg_read(res, MXR_INT_STATUS);
782d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
783d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	/* handling VSYNC */
784d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	if (val & MXR_INT_STATUS_VSYNC) {
785d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		/* interlace scan need to check shadow register */
786d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		if (ctx->interlace) {
787d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim			val_base = mixer_reg_read(res, MXR_GRAPHIC_BASE_S(0));
788d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim			if (ctx->win_data[0].dma_addr != val_base)
789d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim				goto out;
790d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
791d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim			val_base = mixer_reg_read(res, MXR_GRAPHIC_BASE_S(1));
792d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim			if (ctx->win_data[1].dma_addr != val_base)
793d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim				goto out;
794d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		}
795d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
796d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		drm_handle_vblank(drm_hdmi_ctx->drm_dev, ctx->pipe);
797d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		mixer_finish_pageflip(drm_hdmi_ctx->drm_dev, ctx->pipe);
798d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	}
799d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
800d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kimout:
801d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	/* clear interrupts */
802d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	if (~val & MXR_INT_EN_VSYNC) {
803d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		/* vsync interrupt use different bit for read and clear */
804d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		val &= ~MXR_INT_EN_VSYNC;
805d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		val |= MXR_INT_CLEAR_VSYNC;
806d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	}
807d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	mixer_reg_write(res, MXR_INT_STATUS, val);
808d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
809d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	spin_unlock(&res->reg_slock);
810d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
811d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	return IRQ_HANDLED;
812d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim}
813d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
814d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kimstatic void mixer_win_reset(struct mixer_context *ctx)
815d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim{
816d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	struct mixer_resources *res = &ctx->mixer_res;
817d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	unsigned long flags;
818d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	u32 val; /* value stored to register */
819d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
820d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	spin_lock_irqsave(&res->reg_slock, flags);
821d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	mixer_vsync_set_update(ctx, false);
822d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
823d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	mixer_reg_writemask(res, MXR_CFG, MXR_CFG_DST_HDMI, MXR_CFG_DST_MASK);
824d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
825d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	/* set output in RGB888 mode */
826d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	mixer_reg_writemask(res, MXR_CFG, MXR_CFG_OUT_RGB888, MXR_CFG_OUT_MASK);
827d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
828d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	/* 16 beat burst in DMA */
829d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	mixer_reg_writemask(res, MXR_STATUS, MXR_STATUS_16_BURST,
830d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		MXR_STATUS_BURST_MASK);
831d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
83244a0e022b86a8c12ed06c02f52045c8f9f118bb1Joonyoung Shim	/* setting default layer priority: layer1 > layer0 > video
833d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	 * because typical usage scenario would be
83444a0e022b86a8c12ed06c02f52045c8f9f118bb1Joonyoung Shim	 * layer1 - OSD
835d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	 * layer0 - framebuffer
836d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	 * video - video overlay
837d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	 */
83844a0e022b86a8c12ed06c02f52045c8f9f118bb1Joonyoung Shim	val = MXR_LAYER_CFG_GRP1_VAL(3);
83944a0e022b86a8c12ed06c02f52045c8f9f118bb1Joonyoung Shim	val |= MXR_LAYER_CFG_GRP0_VAL(2);
84044a0e022b86a8c12ed06c02f52045c8f9f118bb1Joonyoung Shim	val |= MXR_LAYER_CFG_VP_VAL(1);
841d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	mixer_reg_write(res, MXR_LAYER_CFG, val);
842d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
843d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	/* setting background color */
844d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	mixer_reg_write(res, MXR_BG_COLOR0, 0x008080);
845d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	mixer_reg_write(res, MXR_BG_COLOR1, 0x008080);
846d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	mixer_reg_write(res, MXR_BG_COLOR2, 0x008080);
847d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
848d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	/* setting graphical layers */
849d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
850d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	val  = MXR_GRP_CFG_COLOR_KEY_DISABLE; /* no blank key */
851d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	val |= MXR_GRP_CFG_WIN_BLEND_EN;
852d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	val |= MXR_GRP_CFG_ALPHA_VAL(0xff); /* non-transparent alpha */
853d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
854d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	/* the same configuration for both layers */
855d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	mixer_reg_write(res, MXR_GRAPHIC_CFG(0), val);
856d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
857d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	val |= MXR_GRP_CFG_BLEND_PRE_MUL;
858d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	val |= MXR_GRP_CFG_PIXEL_BLEND_EN;
859d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	mixer_reg_write(res, MXR_GRAPHIC_CFG(1), val);
860d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
861d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	/* configuration of Video Processor Registers */
862d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	vp_win_reset(ctx);
863d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	vp_default_filter(res);
864d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
865d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	/* disable all layers */
866d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	mixer_reg_writemask(res, MXR_CFG, 0, MXR_CFG_GRP0_ENABLE);
867d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	mixer_reg_writemask(res, MXR_CFG, 0, MXR_CFG_GRP1_ENABLE);
868d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	mixer_reg_writemask(res, MXR_CFG, 0, MXR_CFG_VP_ENABLE);
869d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
870d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	mixer_vsync_set_update(ctx, true);
871d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	spin_unlock_irqrestore(&res->reg_slock, flags);
872d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim}
873d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
874d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kimstatic void mixer_resource_poweron(struct mixer_context *ctx)
875d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim{
876d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	struct mixer_resources *res = &ctx->mixer_res;
877d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
878d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
879d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
880d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	clk_enable(res->mixer);
881d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	clk_enable(res->vp);
882d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	clk_enable(res->sclk_mixer);
883d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
884d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	mixer_win_reset(ctx);
885d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim}
886d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
887d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kimstatic void mixer_resource_poweroff(struct mixer_context *ctx)
888d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim{
889d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	struct mixer_resources *res = &ctx->mixer_res;
890d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
891d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
892d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
893d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	clk_disable(res->mixer);
894d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	clk_disable(res->vp);
895d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	clk_disable(res->sclk_mixer);
896d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim}
897d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
898d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kimstatic int mixer_runtime_resume(struct device *dev)
899d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim{
900d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	struct exynos_drm_hdmi_context *ctx = get_mixer_context(dev);
901d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
902d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	DRM_DEBUG_KMS("resume - start\n");
903d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
904f9309d1bf220122659328040db47eede32514656Joonyoung Shim	mixer_resource_poweron(ctx->ctx);
905d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
906d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	return 0;
907d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim}
908d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
909d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kimstatic int mixer_runtime_suspend(struct device *dev)
910d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim{
911d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	struct exynos_drm_hdmi_context *ctx = get_mixer_context(dev);
912d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
913d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	DRM_DEBUG_KMS("suspend - start\n");
914d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
915f9309d1bf220122659328040db47eede32514656Joonyoung Shim	mixer_resource_poweroff(ctx->ctx);
916d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
917d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	return 0;
918d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim}
919d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
920d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kimstatic const struct dev_pm_ops mixer_pm_ops = {
921d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	.runtime_suspend = mixer_runtime_suspend,
922d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	.runtime_resume	 = mixer_runtime_resume,
923d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim};
924d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
925d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kimstatic int __devinit mixer_resources_init(struct exynos_drm_hdmi_context *ctx,
926d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim				 struct platform_device *pdev)
927d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim{
928f9309d1bf220122659328040db47eede32514656Joonyoung Shim	struct mixer_context *mixer_ctx = ctx->ctx;
929d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	struct device *dev = &pdev->dev;
930d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	struct mixer_resources *mixer_res = &mixer_ctx->mixer_res;
931d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	struct resource *res;
932d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	int ret;
933d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
934d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	mixer_res->dev = dev;
935d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	spin_lock_init(&mixer_res->reg_slock);
936d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
937d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	mixer_res->mixer = clk_get(dev, "mixer");
938d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	if (IS_ERR_OR_NULL(mixer_res->mixer)) {
939d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		dev_err(dev, "failed to get clock 'mixer'\n");
940d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		ret = -ENODEV;
941d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		goto fail;
942d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	}
943d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	mixer_res->vp = clk_get(dev, "vp");
944d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	if (IS_ERR_OR_NULL(mixer_res->vp)) {
945d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		dev_err(dev, "failed to get clock 'vp'\n");
946d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		ret = -ENODEV;
947d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		goto fail;
948d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	}
949d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	mixer_res->sclk_mixer = clk_get(dev, "sclk_mixer");
950d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	if (IS_ERR_OR_NULL(mixer_res->sclk_mixer)) {
951d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		dev_err(dev, "failed to get clock 'sclk_mixer'\n");
952d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		ret = -ENODEV;
953d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		goto fail;
954d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	}
955d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	mixer_res->sclk_hdmi = clk_get(dev, "sclk_hdmi");
956d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	if (IS_ERR_OR_NULL(mixer_res->sclk_hdmi)) {
957d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		dev_err(dev, "failed to get clock 'sclk_hdmi'\n");
958d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		ret = -ENODEV;
959d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		goto fail;
960d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	}
961d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	mixer_res->sclk_dac = clk_get(dev, "sclk_dac");
962d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	if (IS_ERR_OR_NULL(mixer_res->sclk_dac)) {
963d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		dev_err(dev, "failed to get clock 'sclk_dac'\n");
964d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		ret = -ENODEV;
965d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		goto fail;
966d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	}
967d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mxr");
968d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	if (res == NULL) {
969d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		dev_err(dev, "get memory resource failed.\n");
970d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		ret = -ENXIO;
971d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		goto fail;
972d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	}
973d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
974d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	clk_set_parent(mixer_res->sclk_mixer, mixer_res->sclk_hdmi);
975d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
976d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	mixer_res->mixer_regs = ioremap(res->start, resource_size(res));
977d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	if (mixer_res->mixer_regs == NULL) {
978d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		dev_err(dev, "register mapping failed.\n");
979d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		ret = -ENXIO;
980d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		goto fail;
981d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	}
982d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
983d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "vp");
984d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	if (res == NULL) {
985d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		dev_err(dev, "get memory resource failed.\n");
986d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		ret = -ENXIO;
987d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		goto fail_mixer_regs;
988d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	}
989d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
990d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	mixer_res->vp_regs = ioremap(res->start, resource_size(res));
991d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	if (mixer_res->vp_regs == NULL) {
992d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		dev_err(dev, "register mapping failed.\n");
993d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		ret = -ENXIO;
994d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		goto fail_mixer_regs;
995d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	}
996d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
997d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "irq");
998d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	if (res == NULL) {
999d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		dev_err(dev, "get interrupt resource failed.\n");
1000d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		ret = -ENXIO;
1001d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		goto fail_vp_regs;
1002d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	}
1003d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
1004d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	ret = request_irq(res->start, mixer_irq_handler, 0, "drm_mixer", ctx);
1005d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	if (ret) {
1006d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		dev_err(dev, "request interrupt failed.\n");
1007d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		goto fail_vp_regs;
1008d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	}
1009d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	mixer_res->irq = res->start;
1010d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
1011d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	return 0;
1012d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
1013d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kimfail_vp_regs:
1014d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	iounmap(mixer_res->vp_regs);
1015d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
1016d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kimfail_mixer_regs:
1017d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	iounmap(mixer_res->mixer_regs);
1018d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
1019d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kimfail:
1020d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	if (!IS_ERR_OR_NULL(mixer_res->sclk_dac))
1021d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		clk_put(mixer_res->sclk_dac);
1022d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	if (!IS_ERR_OR_NULL(mixer_res->sclk_hdmi))
1023d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		clk_put(mixer_res->sclk_hdmi);
1024d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	if (!IS_ERR_OR_NULL(mixer_res->sclk_mixer))
1025d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		clk_put(mixer_res->sclk_mixer);
1026d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	if (!IS_ERR_OR_NULL(mixer_res->vp))
1027d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		clk_put(mixer_res->vp);
1028d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	if (!IS_ERR_OR_NULL(mixer_res->mixer))
1029d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		clk_put(mixer_res->mixer);
1030d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	mixer_res->dev = NULL;
1031d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	return ret;
1032d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim}
1033d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
1034d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kimstatic void mixer_resources_cleanup(struct mixer_context *ctx)
1035d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim{
1036d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	struct mixer_resources *res = &ctx->mixer_res;
1037d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
1038d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	disable_irq(res->irq);
1039d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	free_irq(res->irq, ctx);
1040d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
1041d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	iounmap(res->vp_regs);
1042d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	iounmap(res->mixer_regs);
1043d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim}
1044d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
1045d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kimstatic int __devinit mixer_probe(struct platform_device *pdev)
1046d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim{
1047d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	struct device *dev = &pdev->dev;
1048d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	struct exynos_drm_hdmi_context *drm_hdmi_ctx;
1049d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	struct mixer_context *ctx;
1050d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	int ret;
1051d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
1052d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	dev_info(dev, "probe start\n");
1053d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
1054d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	drm_hdmi_ctx = kzalloc(sizeof(*drm_hdmi_ctx), GFP_KERNEL);
1055d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	if (!drm_hdmi_ctx) {
1056d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		DRM_ERROR("failed to allocate common hdmi context.\n");
1057d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		return -ENOMEM;
1058d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	}
1059d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
1060d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
1061d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	if (!ctx) {
1062d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		DRM_ERROR("failed to alloc mixer context.\n");
1063d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		kfree(drm_hdmi_ctx);
1064d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		return -ENOMEM;
1065d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	}
1066d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
1067d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	drm_hdmi_ctx->ctx = (void *)ctx;
1068d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
1069d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	platform_set_drvdata(pdev, drm_hdmi_ctx);
1070d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
1071d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	/* acquire resources: regs, irqs, clocks */
1072d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	ret = mixer_resources_init(drm_hdmi_ctx, pdev);
1073d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	if (ret)
1074d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		goto fail;
1075d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
1076d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	/* register specific callback point to common hdmi. */
1077578b6065adc8805a8774e4bf3145e18de123f8b2Joonyoung Shim	exynos_mixer_ops_register(&mixer_ops);
1078d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
1079d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	mixer_resource_poweron(ctx);
1080d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
1081d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	return 0;
1082d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
1083d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
1084d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kimfail:
1085d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	dev_info(dev, "probe failed\n");
1086d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	return ret;
1087d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim}
1088d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
1089d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kimstatic int mixer_remove(struct platform_device *pdev)
1090d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim{
1091d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	struct device *dev = &pdev->dev;
1092d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	struct exynos_drm_hdmi_context *drm_hdmi_ctx =
1093d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim					platform_get_drvdata(pdev);
1094f9309d1bf220122659328040db47eede32514656Joonyoung Shim	struct mixer_context *ctx = drm_hdmi_ctx->ctx;
1095d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
10961109bf8bcbf455e4cfebce862f9f9fa5a2f386e9Masanari Iida	dev_info(dev, "remove successful\n");
1097d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
1098d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	mixer_resource_poweroff(ctx);
1099d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	mixer_resources_cleanup(ctx);
1100d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
1101d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	return 0;
1102d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim}
1103d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim
1104d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kimstruct platform_driver mixer_driver = {
1105d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	.driver = {
1106d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		.name = "s5p-mixer",
1107d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		.owner = THIS_MODULE,
1108d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim		.pm = &mixer_pm_ops,
1109d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	},
1110d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	.probe = mixer_probe,
1111d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim	.remove = __devexit_p(mixer_remove),
1112d84083268bd707ebb8ed2f4fc26ebc7a0c453a83Seung-Woo Kim};
1113