xref: /linux/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h (revision 001821b0e79716c4e17c71d8e053a23599a7a508)
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 
218 static inline bool
219 nvkm_gsp_rm(struct nvkm_gsp *gsp)
220 {
221 	return gsp && (gsp->fws.rm || gsp->fw.img);
222 }
223 
224 static inline void *
225 nvkm_gsp_rpc_get(struct nvkm_gsp *gsp, u32 fn, u32 argc)
226 {
227 	return gsp->rm->rpc_get(gsp, fn, argc);
228 }
229 
230 static inline void *
231 nvkm_gsp_rpc_push(struct nvkm_gsp *gsp, void *argv, bool wait, u32 repc)
232 {
233 	return gsp->rm->rpc_push(gsp, argv, wait, repc);
234 }
235 
236 static inline void *
237 nvkm_gsp_rpc_rd(struct nvkm_gsp *gsp, u32 fn, u32 argc)
238 {
239 	void *argv = nvkm_gsp_rpc_get(gsp, fn, argc);
240 
241 	if (IS_ERR_OR_NULL(argv))
242 		return argv;
243 
244 	return nvkm_gsp_rpc_push(gsp, argv, true, argc);
245 }
246 
247 static inline int
248 nvkm_gsp_rpc_wr(struct nvkm_gsp *gsp, void *argv, bool wait)
249 {
250 	void *repv = nvkm_gsp_rpc_push(gsp, argv, wait, 0);
251 
252 	if (IS_ERR(repv))
253 		return PTR_ERR(repv);
254 
255 	return 0;
256 }
257 
258 static inline void
259 nvkm_gsp_rpc_done(struct nvkm_gsp *gsp, void *repv)
260 {
261 	gsp->rm->rpc_done(gsp, repv);
262 }
263 
264 static inline void *
265 nvkm_gsp_rm_ctrl_get(struct nvkm_gsp_object *object, u32 cmd, u32 argc)
266 {
267 	return object->client->gsp->rm->rm_ctrl_get(object, cmd, argc);
268 }
269 
270 static inline int
271 nvkm_gsp_rm_ctrl_push(struct nvkm_gsp_object *object, void *argv, u32 repc)
272 {
273 	return object->client->gsp->rm->rm_ctrl_push(object, argv, repc);
274 }
275 
276 static inline void *
277 nvkm_gsp_rm_ctrl_rd(struct nvkm_gsp_object *object, u32 cmd, u32 repc)
278 {
279 	void *argv = nvkm_gsp_rm_ctrl_get(object, cmd, repc);
280 	int ret;
281 
282 	if (IS_ERR(argv))
283 		return argv;
284 
285 	ret = nvkm_gsp_rm_ctrl_push(object, &argv, repc);
286 	if (ret)
287 		return ERR_PTR(ret);
288 	return argv;
289 }
290 
291 static inline int
292 nvkm_gsp_rm_ctrl_wr(struct nvkm_gsp_object *object, void *argv)
293 {
294 	int ret = nvkm_gsp_rm_ctrl_push(object, &argv, 0);
295 
296 	if (ret)
297 		return ret;
298 	return 0;
299 }
300 
301 static inline void
302 nvkm_gsp_rm_ctrl_done(struct nvkm_gsp_object *object, void *repv)
303 {
304 	object->client->gsp->rm->rm_ctrl_done(object, repv);
305 }
306 
307 static inline void *
308 nvkm_gsp_rm_alloc_get(struct nvkm_gsp_object *parent, u32 handle, u32 oclass, u32 argc,
309 		      struct nvkm_gsp_object *object)
310 {
311 	struct nvkm_gsp_client *client = parent->client;
312 	struct nvkm_gsp *gsp = client->gsp;
313 	void *argv;
314 
315 	object->client = parent->client;
316 	object->parent = parent;
317 	object->handle = handle;
318 
319 	argv = gsp->rm->rm_alloc_get(object, oclass, argc);
320 	if (IS_ERR_OR_NULL(argv)) {
321 		object->client = NULL;
322 		return argv;
323 	}
324 
325 	return argv;
326 }
327 
328 static inline void *
329 nvkm_gsp_rm_alloc_push(struct nvkm_gsp_object *object, void *argv, u32 repc)
330 {
331 	void *repv = object->client->gsp->rm->rm_alloc_push(object, argv, repc);
332 
333 	if (IS_ERR(repv))
334 		object->client = NULL;
335 
336 	return repv;
337 }
338 
339 static inline int
340 nvkm_gsp_rm_alloc_wr(struct nvkm_gsp_object *object, void *argv)
341 {
342 	void *repv = nvkm_gsp_rm_alloc_push(object, argv, 0);
343 
344 	if (IS_ERR(repv))
345 		return PTR_ERR(repv);
346 
347 	return 0;
348 }
349 
350 static inline void
351 nvkm_gsp_rm_alloc_done(struct nvkm_gsp_object *object, void *repv)
352 {
353 	object->client->gsp->rm->rm_alloc_done(object, repv);
354 }
355 
356 static inline int
357 nvkm_gsp_rm_alloc(struct nvkm_gsp_object *parent, u32 handle, u32 oclass, u32 argc,
358 		  struct nvkm_gsp_object *object)
359 {
360 	void *argv = nvkm_gsp_rm_alloc_get(parent, handle, oclass, argc, object);
361 
362 	if (IS_ERR_OR_NULL(argv))
363 		return argv ? PTR_ERR(argv) : -EIO;
364 
365 	return nvkm_gsp_rm_alloc_wr(object, argv);
366 }
367 
368 static inline int
369 nvkm_gsp_rm_free(struct nvkm_gsp_object *object)
370 {
371 	if (object->client)
372 		return object->client->gsp->rm->rm_free(object);
373 
374 	return 0;
375 }
376 
377 static inline int
378 nvkm_gsp_client_ctor(struct nvkm_gsp *gsp, struct nvkm_gsp_client *client)
379 {
380 	if (WARN_ON(!gsp->rm))
381 		return -ENOSYS;
382 
383 	return gsp->rm->client_ctor(gsp, client);
384 }
385 
386 static inline void
387 nvkm_gsp_client_dtor(struct nvkm_gsp_client *client)
388 {
389 	if (client->gsp)
390 		client->gsp->rm->client_dtor(client);
391 }
392 
393 static inline int
394 nvkm_gsp_device_ctor(struct nvkm_gsp_client *client, struct nvkm_gsp_device *device)
395 {
396 	return client->gsp->rm->device_ctor(client, device);
397 }
398 
399 static inline void
400 nvkm_gsp_device_dtor(struct nvkm_gsp_device *device)
401 {
402 	if (device->object.client)
403 		device->object.client->gsp->rm->device_dtor(device);
404 }
405 
406 static inline int
407 nvkm_gsp_client_device_ctor(struct nvkm_gsp *gsp,
408 			    struct nvkm_gsp_client *client, struct nvkm_gsp_device *device)
409 {
410 	int ret = nvkm_gsp_client_ctor(gsp, client);
411 
412 	if (ret == 0) {
413 		ret = nvkm_gsp_device_ctor(client, device);
414 		if (ret)
415 			nvkm_gsp_client_dtor(client);
416 	}
417 
418 	return ret;
419 }
420 
421 struct nvkm_gsp_event {
422 	struct nvkm_gsp_device *device;
423 	u32 id;
424 	nvkm_gsp_event_func func;
425 
426 	struct nvkm_gsp_object object;
427 
428 	struct list_head head;
429 };
430 
431 static inline int
432 nvkm_gsp_device_event_ctor(struct nvkm_gsp_device *device, u32 handle, u32 id,
433 			   nvkm_gsp_event_func func, struct nvkm_gsp_event *event)
434 {
435 	return device->object.client->gsp->rm->event_ctor(device, handle, id, func, event);
436 }
437 
438 static inline void
439 nvkm_gsp_event_dtor(struct nvkm_gsp_event *event)
440 {
441 	struct nvkm_gsp_device *device = event->device;
442 
443 	if (device)
444 		device->object.client->gsp->rm->event_dtor(event);
445 }
446 
447 int nvkm_gsp_intr_stall(struct nvkm_gsp *, enum nvkm_subdev_type, int);
448 int nvkm_gsp_intr_nonstall(struct nvkm_gsp *, enum nvkm_subdev_type, int);
449 
450 int gv100_gsp_new(struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_gsp **);
451 int tu102_gsp_new(struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_gsp **);
452 int tu116_gsp_new(struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_gsp **);
453 int ga100_gsp_new(struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_gsp **);
454 int ga102_gsp_new(struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_gsp **);
455 int ad102_gsp_new(struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_gsp **);
456 #endif
457