summaryrefslogtreecommitdiff
path: root/drivers/video/tegra/dc/dc_priv_defs.h
blob: 83eb84d549d2e066e4817d3a9096c86091144935 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
/*
 * drivers/video/tegra/dc/dc_priv.h
 *
 * Copyright (C) 2010 Google, Inc.
 * Author: Erik Gilling <konkers@android.com>
 *
 * Copyright (c) 2010-2014, NVIDIA CORPORATION, All rights reserved.
 *
 * This software is licensed under the terms of the GNU General Public
 * License version 2, as published by the Free Software Foundation, and
 * may be copied, distributed, and modified under those terms.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 */

#ifndef __DRIVERS_VIDEO_TEGRA_DC_DC_PRIV_DEFS_H
#define __DRIVERS_VIDEO_TEGRA_DC_DC_PRIV_DEFS_H
#include <linux/io.h>
#include <linux/mutex.h>
#include <linux/wait.h>
#include <linux/fb.h>
#include <linux/clk.h>
#include <linux/completion.h>
#include <linux/switch.h>
#include <linux/nvhost.h>
#include <linux/types.h>
#include <linux/clk/tegra.h>
#include <linux/tegra-soc.h>

#include <mach/dc.h>

#include <mach/tegra_dc_ext.h>
#include <mach/isomgr.h>

#include "dc_reg.h"

#define NEED_UPDATE_EMC_ON_EVERY_FRAME (windows_idle_detection_time == 0)

/* 28 bit offset for window clip number */
#define CURSOR_CLIP_SHIFT_BITS(win)	(win << 28)
#define CURSOR_CLIP_GET_WINDOW(reg)	((reg >> 28) & 3)

#define BLANK_ALL	(~0)

static inline u32 ALL_UF_INT(void)
{
	if (tegra_platform_is_fpga())
		return 0;
#if defined(CONFIG_ARCH_TEGRA_14x_SOC) || defined(CONFIG_ARCH_TEGRA_12x_SOC)
	return WIN_A_UF_INT | WIN_B_UF_INT | WIN_C_UF_INT | HC_UF_INT |
		WIN_D_UF_INT | WIN_T_UF_INT;
#else
	return WIN_A_UF_INT | WIN_B_UF_INT | WIN_C_UF_INT;
#endif
}

#if defined(CONFIG_TEGRA_EMC_TO_DDR_CLOCK)
#define EMC_BW_TO_FREQ(bw) (DDR_BW_TO_FREQ(bw) * CONFIG_TEGRA_EMC_TO_DDR_CLOCK)
#else
#define EMC_BW_TO_FREQ(bw) (DDR_BW_TO_FREQ(bw) * 2)
#endif

struct tegra_dc;

struct tegra_dc_blend {
	unsigned z[DC_N_WINDOWS];
	unsigned flags[DC_N_WINDOWS];
	u8 alpha[DC_N_WINDOWS];
};

struct tegra_dc_out_ops {
	/* initialize output.  dc clocks are not on at this point */
	int (*init)(struct tegra_dc *dc);
	/* destroy output.  dc clocks are not on at this point */
	void (*destroy)(struct tegra_dc *dc);
	/* detect connected display.  can sleep.*/
	bool (*detect)(struct tegra_dc *dc);
	/* enable output.  dc clocks are on at this point */
	void (*enable)(struct tegra_dc *dc);
	/* enable dc client.  Panel is enable at this point */
	void (*postpoweron)(struct tegra_dc *dc);
	/* disable output.  dc clocks are on at this point */
	void (*disable)(struct tegra_dc *dc);
	/* dc client is disabled.  dc clocks are on at this point */
	void (*postpoweroff) (struct tegra_dc *dc);
	/* hold output.  keeps dc clocks on. */
	void (*hold)(struct tegra_dc *dc);
	/* release output.  dc clocks may turn off after this. */
	void (*release)(struct tegra_dc *dc);
	/* idle routine of output.  dc clocks may turn off after this. */
	void (*idle)(struct tegra_dc *dc);
	/* suspend output.  dc clocks are on at this point */
	void (*suspend)(struct tegra_dc *dc);
	/* resume output.  dc clocks are on at this point */
	void (*resume)(struct tegra_dc *dc);
	/* mode filter. to provide a list of supported modes*/
	bool (*mode_filter)(const struct tegra_dc *dc,
			struct fb_videomode *mode);
	/* setup pixel clock and parent clock programming */
	long (*setup_clk)(struct tegra_dc *dc, struct clk *clk);
	/*
	 * return true if display client is suspended during OSidle.
	 * If true, dc will not wait on any display client event
	 * during OSidle.
	 */
	bool (*osidle)(struct tegra_dc *dc);
	/* callback after new mode is programmed.
	 * dc clocks are on at this point */
	void (*modeset_notifier)(struct tegra_dc *dc);
	/* Set up interface and sink for partial frame update.
	 */
	int (*partial_update) (struct tegra_dc *dc, unsigned int *xoff,
		unsigned int *yoff, unsigned int *width, unsigned int *height);
};

struct tegra_dc_shift_clk_div {
	unsigned long mul; /* numerator */
	unsigned long div; /* denominator */
};

struct tegra_dc_nvsr_data;

enum tegra_dc_cursor_size {
	TEGRA_DC_CURSOR_SIZE_32X32 = 0,
	TEGRA_DC_CURSOR_SIZE_64X64 = 1,
	TEGRA_DC_CURSOR_SIZE_128X128 = 2,
	TEGRA_DC_CURSOR_SIZE_256X256 = 3,
};

enum tegra_dc_cursor_format {
	TEGRA_DC_CURSOR_FORMAT_2BIT_LEGACY = 0,
	TEGRA_DC_CURSOR_FORMAT_RGBA_NON_PREMULT_ALPHA = 1,
	TEGRA_DC_CURSOR_FORMAT_RGBA_PREMULT_ALPHA = 3,
};

struct tegra_dc {
	struct platform_device		*ndev;
	struct tegra_dc_platform_data	*pdata;

	struct resource			*base_res;
	void __iomem			*base;
	int				irq;

	struct clk			*clk;
#ifdef CONFIG_TEGRA_ISOMGR
	tegra_isomgr_handle		isomgr_handle;
#else
	struct clk			*emc_clk;
#endif
	long				bw_kbps; /* bandwidth in KBps */
	long				new_bw_kbps;
	struct tegra_dc_shift_clk_div	shift_clk_div;

	u32				powergate_id;

	bool				connected;
	bool				enabled;
	bool				suspended;
	bool				blanked;

	/* Some of the setup code could reset display even if
	 * DC is already by bootloader.  This one-time mark is
	 * used to suppress such code blocks during system boot,
	 * a.k.a the call stack above tegra_dc_probe().
	 */
	bool				initialized;

	struct tegra_dc_out		*out;
	struct tegra_dc_out_ops		*out_ops;
	void				*out_data;

	struct tegra_dc_mode		mode;
	s64				frametime_ns;

	struct tegra_dc_win		windows[DC_N_WINDOWS];
	struct tegra_dc_blend		blend;
	int				n_windows;
#ifdef CONFIG_TEGRA_DC_CMU
	struct tegra_dc_cmu		cmu;
	bool				cmu_dirty;
	bool				cmu_enabled;
#endif
	wait_queue_head_t		wq;
	wait_queue_head_t		timestamp_wq;

	struct mutex			lock;
	struct mutex			one_shot_lock;
	struct mutex			one_shot_lp_lock;

	struct resource			*fb_mem;
	struct tegra_fb_info		*fb;
#ifdef CONFIG_ADF_TEGRA
	struct tegra_adf_info		*adf;
#endif

	struct {
		u32			id;
		u32			min;
		u32			max;
	} syncpt[DC_N_WINDOWS];
	u32				vblank_syncpt;
	u32				win_syncpt[DC_N_WINDOWS];

	unsigned long int		valid_windows;
	unsigned long int		win_status;

	unsigned long			underflow_mask;
	struct work_struct		reset_work;

#ifdef CONFIG_SWITCH
	struct switch_dev		modeset_switch;
#endif

	struct completion		frame_end_complete;
	struct completion		crc_complete;
	bool				crc_pending;

	struct work_struct		vblank_work;
	long				vblank_ref_count;
	struct work_struct		vpulse2_work;
	long				vpulse2_ref_count;

	struct {
		u64			underflows;
		u64			underflows_a;
		u64			underflows_b;
		u64			underflows_c;
#if defined(CONFIG_ARCH_TEGRA_14x_SOC) || defined(CONFIG_ARCH_TEGRA_12x_SOC)
		u64			underflows_d;
		u64			underflows_h;
		u64			underflows_t;
#endif
	} stats;

	struct tegra_dc_ext		*ext;

	struct tegra_dc_feature		*feature;
	int				gen1_blend_num;

#ifdef CONFIG_DEBUG_FS
	struct dentry			*debugdir;
#endif
	struct tegra_dc_lut		fb_lut;
	struct delayed_work		underflow_work;
	u32				one_shot_delay_ms;
	struct delayed_work		one_shot_work;
	s64				frame_end_timestamp;
	atomic_t			frame_end_ref;

	bool				mode_dirty;

	u32				reserved_bw;
	u32				available_bw;
	struct tegra_dc_win		tmp_wins[DC_N_WINDOWS];

	struct tegra_edid		*edid;

	struct tegra_dc_nvsr_data *nvsr;

	bool	disp_active_dirty;

	struct tegra_dc_cursor {
		bool dirty;
		bool enabled;
		dma_addr_t phys_addr;
		u32 fg;
		u32 bg;
		unsigned clip_win;
		int x;
		int y;
		enum tegra_dc_cursor_size size;
		enum tegra_dc_cursor_format format;
	} cursor;
};
#endif