summaryrefslogtreecommitdiff
path: root/nouveau/nouveau.h
blob: f3cf8f588a5630f3e44324dc7d50857c52187c0b (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
#ifndef __NOUVEAU_H__
#define __NOUVEAU_H__

#include <stdint.h>
#include <stdbool.h>

#define NOUVEAU_DEVICE_CLASS       0x80000000
#define NOUVEAU_FIFO_CHANNEL_CLASS 0x80000001
#define NOUVEAU_NOTIFIER_CLASS     0x80000002
#define NOUVEAU_PARENT_CLASS       0xffffffff

struct nouveau_list {
	struct nouveau_list *prev;
	struct nouveau_list *next;
};

struct nouveau_object {
	struct nouveau_object *parent;
	uint64_t handle;
	uint32_t oclass;
	uint32_t length;
	void *data;
};

struct nouveau_drm {
	struct nouveau_object client;
	int fd;
	uint32_t version;
	bool nvif;
};

static inline struct nouveau_drm *
nouveau_drm(struct nouveau_object *obj)
{
	while (obj && obj->parent)
		obj = obj->parent;
	return (struct nouveau_drm *)obj;
}

int nouveau_drm_new(int fd, struct nouveau_drm **);
void nouveau_drm_del(struct nouveau_drm **);

struct nouveau_fifo {
	struct nouveau_object *object;
	uint32_t channel;
	uint32_t pushbuf;
	uint64_t unused1[3];
};

struct nv04_fifo {
	struct nouveau_fifo base;
	uint32_t vram;
	uint32_t gart;
	uint32_t notify;
};

struct nvc0_fifo {
	struct nouveau_fifo base;
	uint32_t notify;
};

#define NVE0_FIFO_ENGINE_GR  0x00000001
#define NVE0_FIFO_ENGINE_VP  0x00000002
#define NVE0_FIFO_ENGINE_PPP 0x00000004
#define NVE0_FIFO_ENGINE_BSP 0x00000008
#define NVE0_FIFO_ENGINE_CE0 0x00000010
#define NVE0_FIFO_ENGINE_CE1 0x00000020
#define NVE0_FIFO_ENGINE_ENC 0x00000040

struct nve0_fifo {
	struct {
		struct nouveau_fifo base;
		uint32_t notify;
	};
	uint32_t engine;
};

struct nv04_notify {
	struct nouveau_object *object;
	uint32_t offset;
	uint32_t length;
};

/* Supported class information, provided by the kernel */
struct nouveau_sclass {
	int32_t oclass;
	int minver;
	int maxver;
};

/* Client-provided array describing class versions that are desired.
 *
 * These are used to match against the kernel's list of supported classes.
 */
struct nouveau_mclass {
	int32_t oclass; /* 0 == EOL */
	int version;
	void *data;
};

int  nouveau_object_new(struct nouveau_object *parent, uint64_t handle,
			uint32_t oclass, void *data, uint32_t length,
			struct nouveau_object **);
void nouveau_object_del(struct nouveau_object **);
int  nouveau_object_mthd(struct nouveau_object *, uint32_t mthd,
			 void *data, uint32_t size);
int  nouveau_object_sclass_get(struct nouveau_object *,
			       struct nouveau_sclass **);
void nouveau_object_sclass_put(struct nouveau_sclass **);
int  nouveau_object_mclass(struct nouveau_object *,
			   const struct nouveau_mclass *);

struct nouveau_device {
	struct nouveau_object object;
	int fd;
	uint32_t lib_version;
	uint32_t drm_version;
	uint32_t chipset;
	uint64_t vram_size;
	uint64_t gart_size;
	uint64_t vram_limit;
	uint64_t gart_limit;
};

int  nouveau_device_new(struct nouveau_object *parent, int32_t oclass,
			void *data, uint32_t size, struct nouveau_device **);
int  nouveau_device_wrap(int fd, int close, struct nouveau_device **);
int  nouveau_device_open(const char *busid, struct nouveau_device **);
void nouveau_device_del(struct nouveau_device **);
int  nouveau_getparam(struct nouveau_device *, uint64_t param, uint64_t *value);
int  nouveau_setparam(struct nouveau_device *, uint64_t param, uint64_t value);

struct nouveau_client {
	struct nouveau_device *device;
	int id;
};

int  nouveau_client_new(struct nouveau_device *, struct nouveau_client **);
void nouveau_client_del(struct nouveau_client **);

union nouveau_bo_config {
	struct {
#define NV04_BO_16BPP 0x00000001
#define NV04_BO_32BPP 0x00000002
#define NV04_BO_ZETA  0x00000004
		uint32_t surf_flags;
		uint32_t surf_pitch;
	} nv04;
	struct {
		uint32_t memtype;
		uint32_t tile_mode;
	} nv50;
	struct {
		uint32_t memtype;
		uint32_t tile_mode;
	} nvc0;
	uint32_t data[8];
};

#define NOUVEAU_BO_VRAM    0x00000001
#define NOUVEAU_BO_GART    0x00000002
#define NOUVEAU_BO_APER   (NOUVEAU_BO_VRAM | NOUVEAU_BO_GART)
#define NOUVEAU_BO_RD      0x00000100
#define NOUVEAU_BO_WR      0x00000200
#define NOUVEAU_BO_RDWR   (NOUVEAU_BO_RD | NOUVEAU_BO_WR)
#define NOUVEAU_BO_NOBLOCK 0x00000400
#define NOUVEAU_BO_LOW     0x00001000
#define NOUVEAU_BO_HIGH    0x00002000
#define NOUVEAU_BO_OR      0x00004000
#define NOUVEAU_BO_MAP     0x80000000
#define NOUVEAU_BO_CONTIG  0x40000000
#define NOUVEAU_BO_NOSNOOP 0x20000000
#define NOUVEAU_BO_COHERENT 0x10000000

struct nouveau_bo {
	struct nouveau_device *device;
	uint32_t handle;
	uint64_t size;
	uint32_t flags;
	uint64_t offset;
	void *map;
	union nouveau_bo_config config;
};

int  nouveau_bo_new(struct nouveau_device *, uint32_t flags, uint32_t align,
		    uint64_t size, union nouveau_bo_config *,
		    struct nouveau_bo **);
int  nouveau_bo_wrap(struct nouveau_device *, uint32_t handle,
		     struct nouveau_bo **);
int  nouveau_bo_name_ref(struct nouveau_device *dev, uint32_t name,
			 struct nouveau_bo **);
int  nouveau_bo_name_get(struct nouveau_bo *, uint32_t *name);
void nouveau_bo_ref(struct nouveau_bo *, struct nouveau_bo **);
int  nouveau_bo_map(struct nouveau_bo *, uint32_t access,
		    struct nouveau_client *);
int  nouveau_bo_wait(struct nouveau_bo *, uint32_t access,
		     struct nouveau_client *);
int  nouveau_bo_prime_handle_ref(struct nouveau_device *dev, int prime_fd,
				 struct nouveau_bo **);
int  nouveau_bo_set_prime(struct nouveau_bo *bo, int *prime_fd);

struct nouveau_bufref {
	struct nouveau_list thead;
	struct nouveau_bo *bo;
	uint32_t packet;
	uint32_t flags;
	uint32_t data;
	uint32_t vor;
	uint32_t tor;
	uint32_t priv_data;
	void *priv;
};

struct nouveau_bufctx {
	struct nouveau_client *client;
	struct nouveau_list head;
	struct nouveau_list pending;
	struct nouveau_list current;
	int relocs;
};

int  nouveau_bufctx_new(struct nouveau_client *, int bins,
			struct nouveau_bufctx **);
void nouveau_bufctx_del(struct nouveau_bufctx **);
struct nouveau_bufref *
nouveau_bufctx_refn(struct nouveau_bufctx *, int bin,
		    struct nouveau_bo *, uint32_t flags);
struct nouveau_bufref *
nouveau_bufctx_mthd(struct nouveau_bufctx *, int bin,  uint32_t packet,
		    struct nouveau_bo *, uint64_t data, uint32_t flags,
		    uint32_t vor, uint32_t tor);
void nouveau_bufctx_reset(struct nouveau_bufctx *, int bin);

struct nouveau_pushbuf_krec;
struct nouveau_pushbuf {
	struct nouveau_client *client;
	struct nouveau_object *channel;
	struct nouveau_bufctx *bufctx;
	void (*kick_notify)(struct nouveau_pushbuf *);
	void *user_priv;
	uint32_t rsvd_kick;
	uint32_t flags;
	uint32_t *cur;
	uint32_t *end;
};

struct nouveau_pushbuf_refn {
	struct nouveau_bo *bo;
	uint32_t flags;
};

int  nouveau_pushbuf_new(struct nouveau_client *, struct nouveau_object *channel,
			 int nr, uint32_t size, bool immediate,
			 struct nouveau_pushbuf **);
void nouveau_pushbuf_del(struct nouveau_pushbuf **);
int  nouveau_pushbuf_space(struct nouveau_pushbuf *, uint32_t dwords,
			   uint32_t relocs, uint32_t pushes);
void nouveau_pushbuf_data(struct nouveau_pushbuf *, struct nouveau_bo *,
			  uint64_t offset, uint64_t length);
int  nouveau_pushbuf_refn(struct nouveau_pushbuf *,
			  struct nouveau_pushbuf_refn *, int nr);
/* Emits a reloc into the push buffer at the current position, you *must*
 * have previously added the referenced buffer to a buffer context, and
 * validated it against the current push buffer.
 */
void nouveau_pushbuf_reloc(struct nouveau_pushbuf *, struct nouveau_bo *,
			   uint32_t data, uint32_t flags,
			   uint32_t vor, uint32_t tor);
int  nouveau_pushbuf_validate(struct nouveau_pushbuf *);
uint32_t nouveau_pushbuf_refd(struct nouveau_pushbuf *, struct nouveau_bo *);
int  nouveau_pushbuf_kick(struct nouveau_pushbuf *, struct nouveau_object *channel);
struct nouveau_bufctx *
nouveau_pushbuf_bufctx(struct nouveau_pushbuf *, struct nouveau_bufctx *);

#endif