summaryrefslogtreecommitdiff
path: root/include/linux/nvhost.h
blob: b4a3bafbfbab753db58227971bc58294cf07f16e (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
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
/*
 * include/linux/nvhost.h
 *
 * Tegra graphics host driver
 *
 * Copyright (c) 2009-2014, NVIDIA Corporation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * 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.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */

#ifndef __LINUX_NVHOST_H
#define __LINUX_NVHOST_H

#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/types.h>
#include <linux/devfreq.h>
#include <linux/platform_device.h>
#include <linux/pm_domain.h>
#include <linux/pm_qos.h>
#include <linux/time.h>

struct nvhost_master;
struct nvhost_hwctx;
struct nvhost_device_power_attr;
struct nvhost_device_profile;
struct mem_mgr;
struct nvhost_as_moduleops;

#define NVHOST_MODULE_MAX_CLOCKS		7
#define NVHOST_MODULE_MAX_POWERGATE_IDS 	2
#define NVHOST_MODULE_MAX_SYNCPTS		8
#define NVHOST_MODULE_MAX_WAITBASES		3
#define NVHOST_MODULE_MAX_MODMUTEXES		5
#define NVHOST_MODULE_MAX_IORESOURCE_MEM	3
#define NVHOST_MODULE_NO_POWERGATE_IDS		.powergate_ids = {-1, -1}
#define NVHOST_DEFAULT_CLOCKGATE_DELAY		.clockgate_delay = 25
#define NVHOST_MODULE_MAX_IORESOURCE_MEM 3
#define NVHOST_NAME_SIZE			24
#define NVSYNCPT_INVALID			(-1)

#define NVSYNCPT_GRAPHICS_HOST		(0)	/* t20, t30, t114, t148 */

#define NVSYNCPT_AVP_0			(10)	/*  t20, t30, t114, t148 */
#define NVSYNCPT_2D_0			(18)
#define NVSYNCPT_2D_1			(19)
#define NVSYNCPT_3D			(22)
#define NVSYNCPT_VBLANK0		(26)	/* t20, t30, t114, t148 */
#define NVSYNCPT_VBLANK1		(27)	/* t20, t30, t114, t148 */

#define NVWAITBASE_2D_0			(1)	/* t20, t30, t114 */
#define NVWAITBASE_2D_1			(2)	/* t20, t30, t114 */
#define NVWAITBASE_3D			(3)	/* t20, t30, t114 */
#define NVWAITBASE_MPE			(4)	/* t20, t30 */
#define NVWAITBASE_MSENC		(4)	/* t114, t148 */
#define NVWAITBASE_TSEC			(5)	/* t114, t148 */

#define NVMODMUTEX_2D_FULL		(1)	/* t20, t30, t114, t148 */
#define NVMODMUTEX_ISP_0		(1)	/* t124 */
#define NVMODMUTEX_2D_SIMPLE		(2)	/* t20, t30, t114, t148 */
#define NVMODMUTEX_ISP_1		(2)	/* t124 */
#define NVMODMUTEX_2D_SB_A		(3)	/* t20, t30, t114, t148 */
#define NVMODMUTEX_2D_SB_B		(4)	/* t20, t30, t114, t148 */
#define NVMODMUTEX_3D			(5)	/* t20, t30, t114, t148 */
#define NVMODMUTEX_DISPLAYA		(6)	/* t20, t30, t114, t148 */
#define NVMODMUTEX_DISPLAYB		(7)	/* t20, t30, t114, t148 */
#define NVMODMUTEX_VI			(8)	/* t20, t30, t114 */
#define NVMODMUTEX_VI_0			(8)	/* t148 */
#define NVMODMUTEX_DSI			(9)	/* t20, t30, t114, t148 */
#define NVMODMUTEX_VIC			(10)	/* t124 */
#define NVMODMUTEX_VI_1			(11)	/* t124 */

enum nvhost_power_sysfs_attributes {
	NVHOST_POWER_SYSFS_ATTRIB_CLOCKGATE_DELAY = 0,
	NVHOST_POWER_SYSFS_ATTRIB_POWERGATE_DELAY,
	NVHOST_POWER_SYSFS_ATTRIB_MAX
};

struct nvhost_notification {
	struct {			/* 0000- */
		__u32 nanoseconds[2];	/* nanoseconds since Jan. 1, 1970 */
	} time_stamp;			/* -0007 */
	__u32 info32;	/* info returned depends on method 0008-000b */
#define	NVHOST_CHANNEL_FIFO_ERROR_IDLE_TIMEOUT	8
#define	NVHOST_CHANNEL_GR_ERROR_SW_NOTIFY	13
#define	NVHOST_CHANNEL_GR_SEMAPHORE_TIMEOUT	24
#define	NVHOST_CHANNEL_GR_ILLEGAL_NOTIFY	25
#define	NVHOST_CHANNEL_FIFO_ERROR_MMU_ERR_FLT	31
	__u16 info16;	/* info returned depends on method 000c-000d */
	__u16 status;	/* user sets bit 15, NV sets status 000e-000f */
};

struct nvhost_clock {
	char *name;
	unsigned long default_rate;
	u32 moduleid;
	int reset;
	unsigned long devfreq_rate;
};

struct nvhost_device_data {
	int		version;	/* ip version number of device */
	int		id;		/* Separates clients of same hw */
	int		index;		/* Hardware channel number */
	void __iomem	*aperture[NVHOST_MODULE_MAX_IORESOURCE_MEM];
	struct device_dma_parameters dma_parms;

	u32		syncpts[NVHOST_MODULE_MAX_SYNCPTS];
	u32		syncpt_base;	/* Device sync point base */
	u32		waitbases[NVHOST_MODULE_MAX_WAITBASES];
	u32		modulemutexes[NVHOST_MODULE_MAX_MODMUTEXES];
	u32		moduleid;	/* Module id for user space API */

	u32		class;		/* Device class */
	bool		exclusive;	/* True if only one user at a time */
	bool		keepalive;	/* Do not power gate when opened */
	bool		waitbasesync;	/* Force sync of wait bases */
	bool		powerup_reset;	/* Do a reset after power un-gating */
	bool		serialize;	/* Serialize submits in the channel */

	int		powergate_ids[NVHOST_MODULE_MAX_POWERGATE_IDS];
	bool		can_powergate;	/* True if module can be power gated */
	int		clockgate_delay;/* Delay before clock gated */
	int		powergate_delay;/* Delay before power gated */
	struct nvhost_clock clocks[NVHOST_MODULE_MAX_CLOCKS];/* Clock names */

	struct platform_device *master;	/* Master of a slave device */
	struct platform_device *slave;	/* Slave device to create in probe */
	int		slave_initialized;

	int		num_clks;	/* Number of clocks opened for dev */
	struct clk	*clk[NVHOST_MODULE_MAX_CLOCKS];
	struct mutex	lock;		/* Power management lock */
	struct list_head client_list;	/* List of clients and rate requests */

	struct nvhost_channel *channel;	/* Channel assigned for the module */

	/* device node for channel operations */
	struct device *node;
	struct cdev cdev;

	/* device node for ctrl block */
	struct device *ctrl_node;
	struct cdev ctrl_cdev;
	const struct file_operations *ctrl_ops;    /* ctrl ops for the module */

	/* address space operations */
	const struct nvhost_as_moduleops *as_ops;

	/* module debugger */
	struct device *dbg_node;
	struct cdev dbg_cdev;
	const struct file_operations *dbg_ops;

	/* module profiler */
	struct device *prof_node;
	struct cdev prof_cdev;
	const struct file_operations *prof_ops;

	struct kobject *power_kobj;	/* kobject to hold power sysfs entries */
	struct nvhost_device_power_attr *power_attrib;	/* sysfs attributes */
	struct dentry *debugfs;		/* debugfs directory */

	u32 nvhost_timeout_default;

	/* QoS id that denotes minimum frequency */
	unsigned int			qos_id;
	/* Data for devfreq usage */
	struct devfreq			*power_manager;
	/* Private device profile data */
	struct nvhost_device_profile	*power_profile;
	/* Should we read load estimate from hardware? */
	bool				actmon_enabled;
	/* Should we do linear emc scaling? */
	bool				linear_emc;
	/* Should the load value be delivered forward to edp? */
	bool				gpu_edp_device;
	/* Offset to actmon registers */
	u32				actmon_regs;
	/* Devfreq governor name */
	const char			*devfreq_governor;

	void *private_data;		/* private platform data */
	struct platform_device *pdev;	/* owner platform_device */

	struct dev_pm_qos_request no_poweroff_req;

#ifdef CONFIG_PM_GENERIC_DOMAINS
	struct generic_pm_domain pd;	/* power domain representing power partition */
#endif
	/* forces the context restore gather for each submit */
	bool		force_context_restore;

	/* Finalize power on. Can be used for context restore. */
	int (*finalize_poweron)(struct platform_device *dev);

	/*
	 * Reset the unit. Used for timeout recovery, resetting the unit on
	 * probe and when un-powergating.
	 */
	void (*reset)(struct platform_device *dev);

	/* Device is busy. */
	void (*busy)(struct platform_device *);

	/* Device is idle. */
	void (*idle)(struct platform_device *);

	/* Device is going to be suspended */
	void (*suspend_ndev)(struct device *);

	/* Scaling init is run on device registration */
	void (*scaling_init)(struct platform_device *dev);

	/* Scaling deinit is called on device unregistration */
	void (*scaling_deinit)(struct platform_device *dev);

	/* Postscale callback is called after frequency change */
	void (*scaling_post_cb)(struct nvhost_device_profile *profile,
				unsigned long freq);

	/* Device is initialized */
	int (*init)(struct platform_device *dev);

	/* Device is de-initialized. */
	void (*deinit)(struct platform_device *dev);

	/* Preparing for power off. Used for context save. */
	int (*prepare_poweroff)(struct platform_device *dev);

	/* Allocates a context handler for the device */
	struct nvhost_hwctx_handler *(*alloc_hwctx_handler)(u32 syncpt,
			u32 waitbase, struct nvhost_channel *ch);

	/* Read module register into memory */
	int (*read_reg)(struct platform_device *dev,
			struct nvhost_channel *ch,
			struct nvhost_hwctx *hwctx,
			u32 offset,
			u32 *value);

	/* Callback when a clock is changed */
	void (*update_clk)(struct platform_device *dev);
};


static inline
struct nvhost_device_data *nvhost_get_devdata(struct platform_device *pdev)
{
	return (struct nvhost_device_data *)platform_get_drvdata(pdev);
}

enum nvhost_devfreq_busy {
	DEVICE_IDLE = 0,
	DEVICE_BUSY = 1
};

struct nvhost_devfreq_ext_stat {
	enum nvhost_devfreq_busy	busy;
	unsigned long			max_freq;
	unsigned long			min_freq;
};

struct nvhost_device_power_attr {
	struct platform_device *ndev;
	struct kobj_attribute power_attr[NVHOST_POWER_SYSFS_ATTRIB_MAX];
};

void host1x_writel(struct platform_device *dev, u32 r, u32 v);
u32 host1x_readl(struct platform_device *dev, u32 r);

/* public host1x power management APIs */
bool nvhost_module_powered_ext(struct platform_device *dev);
int nvhost_module_busy_ext(struct platform_device *dev);
void nvhost_module_idle_ext(struct platform_device *dev);

/* public host1x sync-point management APIs */
u32 nvhost_get_syncpt_client_managed(const char *syncpt_name);
u32 nvhost_syncpt_incr_max_ext(struct platform_device *dev, u32 id, u32 incrs);
void nvhost_syncpt_cpu_incr_ext(struct platform_device *dev, u32 id);
u32 nvhost_syncpt_read_ext(struct platform_device *dev, u32 id);
int nvhost_syncpt_wait_timeout_ext(struct platform_device *dev, u32 id, u32 thresh,
	u32 timeout, u32 *value, struct timespec *ts);
int nvhost_syncpt_create_fence_single_ext(struct platform_device *dev,
	u32 id, u32 thresh, const char *name, int *fence_fd);

#ifdef CONFIG_TEGRA_GK20A
int nvhost_vpr_info_fetch(void);
#else
static inline int nvhost_vpr_info_fetch(void)
{
	return 0;
}
#endif

/* Hacky way to get access to struct nvhost_device_data for VI device. */
extern struct nvhost_device_data t20_vi_info;
extern struct nvhost_device_data t30_vi_info;
extern struct nvhost_device_data t11_vi_info;
extern struct nvhost_device_data t14_vi_info;

#endif