xref: /linux/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h (revision b3e328dcedc11f1a17dfbc9baedebf6938b5c878)
1 #ifndef __NVKM_GSP_H__
2 #define __NVKM_GSP_H__
3 #define nvkm_gsp(p) container_of((p), struct nvkm_gsp, subdev)
4 #include <core/subdev.h>
5 #include <core/falcon.h>
6 #include <core/firmware.h>
7 
8 #define GSP_PAGE_SHIFT 12
9 #define GSP_PAGE_SIZE  BIT(GSP_PAGE_SHIFT)
10 
11 struct nvkm_gsp_mem {
12 	size_t size;
13 	void *data;
14 	dma_addr_t addr;
15 };
16 
17 struct nvkm_gsp_radix3 {
18 	struct nvkm_gsp_mem mem[3];
19 };
20 
21 int nvkm_gsp_sg(struct nvkm_device *, u64 size, struct sg_table *);
22 void nvkm_gsp_sg_free(struct nvkm_device *, struct sg_table *);
23 
24 typedef int (*nvkm_gsp_msg_ntfy_func)(void *priv, u32 fn, void *repv, u32 repc);
25 
26 struct nvkm_gsp_event;
27 typedef void (*nvkm_gsp_event_func)(struct nvkm_gsp_event *, void *repv, u32 repc);
28 
29 struct nvkm_gsp {
30 	const struct nvkm_gsp_func *func;
31 	struct nvkm_subdev subdev;
32 
33 	struct nvkm_falcon falcon;
34 
35 	struct {
36 		struct {
37 			const struct firmware *load;
38 			const struct firmware *unload;
39 		} booter;
40 		const struct firmware *bl;
41 		const struct firmware *rm;
42 	} fws;
43 
44 	struct nvkm_firmware fw;
45 	struct nvkm_gsp_mem sig;
46 	struct nvkm_gsp_radix3 radix3;
47 
48 	struct {
49 		struct {
50 			struct {
51 				u64 addr;
52 				u64 size;
53 			} vga_workspace;
54 			u64 addr;
55 			u64 size;
56 		} bios;
57 		struct {
58 			struct {
59 				u64 addr;
60 				u64 size;
61 			} frts, boot, elf, heap;
62 			u64 addr;
63 			u64 size;
64 		} wpr2;
65 		struct {
66 			u64 addr;
67 			u64 size;
68 		} heap;
69 		u64 addr;
70 		u64 size;
71 
72 		struct {
73 			u64 addr;
74 			u64 size;
75 		} region[16];
76 		int region_nr;
77 		u32 rsvd_size;
78 	} fb;
79 
80 	struct {
81 		struct nvkm_falcon_fw load;
82 		struct nvkm_falcon_fw unload;
83 	} booter;
84 
85 	struct {
86 		struct nvkm_gsp_mem fw;
87 		u32 code_offset;
88 		u32 data_offset;
89 		u32 manifest_offset;
90 		u32 app_version;
91 	} boot;
92 
93 	struct nvkm_gsp_mem libos;
94 	struct nvkm_gsp_mem loginit;
95 	struct nvkm_gsp_mem logintr;
96 	struct nvkm_gsp_mem logrm;
97 	struct nvkm_gsp_mem rmargs;
98 
99 	struct nvkm_gsp_mem wpr_meta;
100 
101 	struct {
102 		struct sg_table sgt;
103 		struct nvkm_gsp_radix3 radix3;
104 		struct nvkm_gsp_mem meta;
105 	} sr;
106 
107 	struct {
108 		struct nvkm_gsp_mem mem;
109 
110 		struct {
111 			int   nr;
112 			u32 size;
113 			u64 *ptr;
114 		} ptes;
115 
116 		struct {
117 			u32  size;
118 			void *ptr;
119 		} cmdq, msgq;
120 	} shm;
121 
122 	struct nvkm_gsp_cmdq {
123 		struct mutex mutex;
124 		u32 cnt;
125 		u32 seq;
126 		u32 *wptr;
127 		u32 *rptr;
128 	} cmdq;
129 
130 	struct nvkm_gsp_msgq {
131 		struct mutex mutex;
132 		u32 cnt;
133 		u32 *wptr;
134 		u32 *rptr;
135 		struct nvkm_gsp_msgq_ntfy {
136 			u32 fn;
137 			nvkm_gsp_msg_ntfy_func func;
138 			void *priv;
139 		} ntfy[16];
140 		int ntfy_nr;
141 		struct work_struct work;
142 	} msgq;
143 
144 	bool running;
145 
146 	/* Internal GSP-RM control handles. */
147 	struct {
148 		struct nvkm_gsp_client {
149 			struct nvkm_gsp_object {
150 				struct nvkm_gsp_client *client;
151 				struct nvkm_gsp_object *parent;
152 				u32 handle;
153 			} object;
154 
155 			struct nvkm_gsp *gsp;
156 
157 			struct list_head events;
158 		} client;
159 
160 		struct nvkm_gsp_device {
161 			struct nvkm_gsp_object object;
162 			struct nvkm_gsp_object subdevice;
163 		} device;
164 	} internal;
165 
166 	struct {
167 		enum nvkm_subdev_type type;
168 		int inst;
169 		u32 stall;
170 		u32 nonstall;
171 	} intr[32];
172 	int intr_nr;
173 
174 	struct {
175 		u64 rm_bar1_pdb;
176 		u64 rm_bar2_pdb;
177 	} bar;
178 
179 	struct {
180 		u8 gpcs;
181 		u8 tpcs;
182 	} gr;
183 
184 	const struct nvkm_gsp_rm {
185 		void *(*rpc_get)(struct nvkm_gsp *, u32 fn, u32 argc);
186 		void *(*rpc_push)(struct nvkm_gsp *, void *argv, bool wait, u32 repc);
187 		void (*rpc_done)(struct nvkm_gsp *gsp, void *repv);
188 
189 		void *(*rm_ctrl_get)(struct nvkm_gsp_object *, u32 cmd, u32 argc);
190 		int (*rm_ctrl_push)(struct nvkm_gsp_object *, void **argv, u32 repc);
191 		void (*rm_ctrl_done)(struct nvkm_gsp_object *, void *repv);
192 
193 		void *(*rm_alloc_get)(struct nvkm_gsp_object *, u32 oclass, u32 argc);
194 		void *(*rm_alloc_push)(struct nvkm_gsp_object *, void *argv, u32 repc);
195 		void (*rm_alloc_done)(struct nvkm_gsp_object *, void *repv);
196 
197 		int (*rm_free)(struct nvkm_gsp_object *);
198 
199 		int (*client_ctor)(struct nvkm_gsp *, struct nvkm_gsp_client *);
200 		void (*client_dtor)(struct nvkm_gsp_client *);
201 
202 		int (*device_ctor)(struct nvkm_gsp_client *, struct nvkm_gsp_device *);
203 		void (*device_dtor)(struct nvkm_gsp_device *);
204 
205 		int (*event_ctor)(struct nvkm_gsp_device *, u32 handle, u32 id,
206 				  nvkm_gsp_event_func, struct nvkm_gsp_event *);
207 		void (*event_dtor)(struct nvkm_gsp_event *);
208 	} *rm;
209 
210 	struct {
211 		struct mutex mutex;;
212 		struct idr idr;
213 	} client_id;
214 
215 	/* A linked list of registry items. The registry RPC will be built from it. */
216 	struct list_head registry_list;
217 
218 	/* The size of the registry RPC */
219 	size_t registry_rpc_size;
220 };
221 
222 static inline bool
223 nvkm_gsp_rm(struct nvkm_gsp *gsp)
224 {
225 	return gsp && (gsp->fws.rm || gsp->fw.img);
226 }
227 
228 static inline void *
229 nvkm_gsp_rpc_get(struct nvkm_gsp *gsp, u32 fn, u32 argc)
230 {
231 	return gsp->rm->rpc_get(gsp, fn, argc);
232 }
233 
234 static inline void *
235 nvkm_gsp_rpc_push(struct nvkm_gsp *gsp, void *argv, bool wait, u32 repc)
236 {
237 	return gsp->rm->rpc_push(gsp, argv, wait, repc);
238 }
239 
240 static inline void *
241 nvkm_gsp_rpc_rd(struct nvkm_gsp *gsp, u32 fn, u32 argc)
242 {
243 	void *argv = nvkm_gsp_rpc_get(gsp, fn, argc);
244 
245 	if (IS_ERR_OR_NULL(argv))
246 		return argv;
247 
248 	return nvkm_gsp_rpc_push(gsp, argv, true, argc);
249 }
250 
251 static inline int
252 nvkm_gsp_rpc_wr(struct nvkm_gsp *gsp, void *argv, bool wait)
253 {
254 	void *repv = nvkm_gsp_rpc_push(gsp, argv, wait, 0);
255 
256 	if (IS_ERR(repv))
257 		return PTR_ERR(repv);
258 
259 	return 0;
260 }
261 
262 static inline void
263 nvkm_gsp_rpc_done(struct nvkm_gsp *gsp, void *repv)
264 {
265 	gsp->rm->rpc_done(gsp, repv);
266 }
267 
268 static inline void *
269 nvkm_gsp_rm_ctrl_get(struct nvkm_gsp_object *object, u32 cmd, u32 argc)
270 {
271 	return object->client->gsp->rm->rm_ctrl_get(object, cmd, argc);
272 }
273 
274 static inline int
275 nvkm_gsp_rm_ctrl_push(struct nvkm_gsp_object *object, void *argv, u32 repc)
276 {
277 	return object->client->gsp->rm->rm_ctrl_push(object, argv, repc);
278 }
279 
280 static inline void *
281 nvkm_gsp_rm_ctrl_rd(struct nvkm_gsp_object *object, u32 cmd, u32 repc)
282 {
283 	void *argv = nvkm_gsp_rm_ctrl_get(object, cmd, repc);
284 	int ret;
285 
286 	if (IS_ERR(argv))
287 		return argv;
288 
289 	ret = nvkm_gsp_rm_ctrl_push(object, &argv, repc);
290 	if (ret)
291 		return ERR_PTR(ret);
292 	return argv;
293 }
294 
295 static inline int
296 nvkm_gsp_rm_ctrl_wr(struct nvkm_gsp_object *object, void *argv)
297 {
298 	int ret = nvkm_gsp_rm_ctrl_push(object, &argv, 0);
299 
300 	if (ret)
301 		return ret;
302 	return 0;
303 }
304 
305 static inline void
306 nvkm_gsp_rm_ctrl_done(struct nvkm_gsp_object *object, void *repv)
307 {
308 	object->client->gsp->rm->rm_ctrl_done(object, repv);
309 }
310 
311 static inline void *
312 nvkm_gsp_rm_alloc_get(struct nvkm_gsp_object *parent, u32 handle, u32 oclass, u32 argc,
313 		      struct nvkm_gsp_object *object)
314 {
315 	struct nvkm_gsp_client *client = parent->client;
316 	struct nvkm_gsp *gsp = client->gsp;
317 	void *argv;
318 
319 	object->client = parent->client;
320 	object->parent = parent;
321 	object->handle = handle;
322 
323 	argv = gsp->rm->rm_alloc_get(object, oclass, argc);
324 	if (IS_ERR_OR_NULL(argv)) {
325 		object->client = NULL;
326 		return argv;
327 	}
328 
329 	return argv;
330 }
331 
332 static inline void *
333 nvkm_gsp_rm_alloc_push(struct nvkm_gsp_object *object, void *argv, u32 repc)
334 {
335 	void *repv = object->client->gsp->rm->rm_alloc_push(object, argv, repc);
336 
337 	if (IS_ERR(repv))
338 		object->client = NULL;
339 
340 	return repv;
341 }
342 
343 static inline int
344 nvkm_gsp_rm_alloc_wr(struct nvkm_gsp_object *object, void *argv)
345 {
346 	void *repv = nvkm_gsp_rm_alloc_push(object, argv, 0);
347 
348 	if (IS_ERR(repv))
349 		return PTR_ERR(repv);
350 
351 	return 0;
352 }
353 
354 static inline void
355 nvkm_gsp_rm_alloc_done(struct nvkm_gsp_object *object, void *repv)
356 {
357 	object->client->gsp->rm->rm_alloc_done(object, repv);
358 }
359 
360 static inline int
361 nvkm_gsp_rm_alloc(struct nvkm_gsp_object *parent, u32 handle, u32 oclass, u32 argc,
362 		  struct nvkm_gsp_object *object)
363 {
364 	void *argv = nvkm_gsp_rm_alloc_get(parent, handle, oclass, argc, object);
365 
366 	if (IS_ERR_OR_NULL(argv))
367 		return argv ? PTR_ERR(argv) : -EIO;
368 
369 	return nvkm_gsp_rm_alloc_wr(object, argv);
370 }
371 
372 static inline int
373 nvkm_gsp_rm_free(struct nvkm_gsp_object *object)
374 {
375 	if (object->client)
376 		return object->client->gsp->rm->rm_free(object);
377 
378 	return 0;
379 }
380 
381 static inline int
382 nvkm_gsp_client_ctor(struct nvkm_gsp *gsp, struct nvkm_gsp_client *client)
383 {
384 	if (WARN_ON(!gsp->rm))
385 		return -ENOSYS;
386 
387 	return gsp->rm->client_ctor(gsp, client);
388 }
389 
390 static inline void
391 nvkm_gsp_client_dtor(struct nvkm_gsp_client *client)
392 {
393 	if (client->gsp)
394 		client->gsp->rm->client_dtor(client);
395 }
396 
397 static inline int
398 nvkm_gsp_device_ctor(struct nvkm_gsp_client *client, struct nvkm_gsp_device *device)
399 {
400 	return client->gsp->rm->device_ctor(client, device);
401 }
402 
403 static inline void
404 nvkm_gsp_device_dtor(struct nvkm_gsp_device *device)
405 {
406 	if (device->object.client)
407 		device->object.client->gsp->rm->device_dtor(device);
408 }
409 
410 static inline int
411 nvkm_gsp_client_device_ctor(struct nvkm_gsp *gsp,
412 			    struct nvkm_gsp_client *client, struct nvkm_gsp_device *device)
413 {
414 	int ret = nvkm_gsp_client_ctor(gsp, client);
415 
416 	if (ret == 0) {
417 		ret = nvkm_gsp_device_ctor(client, device);
418 		if (ret)
419 			nvkm_gsp_client_dtor(client);
420 	}
421 
422 	return ret;
423 }
424 
425 struct nvkm_gsp_event {
426 	struct nvkm_gsp_device *device;
427 	u32 id;
428 	nvkm_gsp_event_func func;
429 
430 	struct nvkm_gsp_object object;
431 
432 	struct list_head head;
433 };
434 
435 static inline int
436 nvkm_gsp_device_event_ctor(struct nvkm_gsp_device *device, u32 handle, u32 id,
437 			   nvkm_gsp_event_func func, struct nvkm_gsp_event *event)
438 {
439 	return device->object.client->gsp->rm->event_ctor(device, handle, id, func, event);
440 }
441 
442 static inline void
443 nvkm_gsp_event_dtor(struct nvkm_gsp_event *event)
444 {
445 	struct nvkm_gsp_device *device = event->device;
446 
447 	if (device)
448 		device->object.client->gsp->rm->event_dtor(event);
449 }
450 
451 int nvkm_gsp_intr_stall(struct nvkm_gsp *, enum nvkm_subdev_type, int);
452 int nvkm_gsp_intr_nonstall(struct nvkm_gsp *, enum nvkm_subdev_type, int);
453 
454 int gv100_gsp_new(struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_gsp **);
455 int tu102_gsp_new(struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_gsp **);
456 int tu116_gsp_new(struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_gsp **);
457 int ga100_gsp_new(struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_gsp **);
458 int ga102_gsp_new(struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_gsp **);
459 int ad102_gsp_new(struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_gsp **);
460 #endif
461