463 lines · c
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 129#define GSP_PAGE_SIZE BIT(GSP_PAGE_SHIFT)10 11struct nvkm_gsp_mem {12 size_t size;13 void *data;14 dma_addr_t addr;15};16 17struct nvkm_gsp_radix3 {18 struct nvkm_gsp_mem lvl0;19 struct nvkm_gsp_mem lvl1;20 struct sg_table lvl2;21};22 23int nvkm_gsp_sg(struct nvkm_device *, u64 size, struct sg_table *);24void nvkm_gsp_sg_free(struct nvkm_device *, struct sg_table *);25 26typedef int (*nvkm_gsp_msg_ntfy_func)(void *priv, u32 fn, void *repv, u32 repc);27 28struct nvkm_gsp_event;29typedef void (*nvkm_gsp_event_func)(struct nvkm_gsp_event *, void *repv, u32 repc);30 31struct 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 224static inline bool225nvkm_gsp_rm(struct nvkm_gsp *gsp)226{227 return gsp && (gsp->fws.rm || gsp->fw.img);228}229 230static inline void *231nvkm_gsp_rpc_get(struct nvkm_gsp *gsp, u32 fn, u32 argc)232{233 return gsp->rm->rpc_get(gsp, fn, argc);234}235 236static inline void *237nvkm_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 242static inline void *243nvkm_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 253static inline int254nvkm_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 264static inline void265nvkm_gsp_rpc_done(struct nvkm_gsp *gsp, void *repv)266{267 gsp->rm->rpc_done(gsp, repv);268}269 270static inline void *271nvkm_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 276static inline int277nvkm_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 282static inline void *283nvkm_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 297static inline int298nvkm_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 307static inline void308nvkm_gsp_rm_ctrl_done(struct nvkm_gsp_object *object, void *repv)309{310 object->client->gsp->rm->rm_ctrl_done(object, repv);311}312 313static inline void *314nvkm_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 334static inline void *335nvkm_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 345static inline int346nvkm_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 356static inline void357nvkm_gsp_rm_alloc_done(struct nvkm_gsp_object *object, void *repv)358{359 object->client->gsp->rm->rm_alloc_done(object, repv);360}361 362static inline int363nvkm_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 374static inline int375nvkm_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 383static inline int384nvkm_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 392static inline void393nvkm_gsp_client_dtor(struct nvkm_gsp_client *client)394{395 if (client->gsp)396 client->gsp->rm->client_dtor(client);397}398 399static inline int400nvkm_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 405static inline void406nvkm_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 412static inline int413nvkm_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 427struct 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 437static inline int438nvkm_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 444static inline void445nvkm_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 453int nvkm_gsp_intr_stall(struct nvkm_gsp *, enum nvkm_subdev_type, int);454int nvkm_gsp_intr_nonstall(struct nvkm_gsp *, enum nvkm_subdev_type, int);455 456int gv100_gsp_new(struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_gsp **);457int tu102_gsp_new(struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_gsp **);458int tu116_gsp_new(struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_gsp **);459int ga100_gsp_new(struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_gsp **);460int ga102_gsp_new(struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_gsp **);461int ad102_gsp_new(struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_gsp **);462#endif463