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