Lines Matching +full:rpc +full:- +full:if
49 #include <nvrm/535.113.01/nvidia/generated/g_rpc-structures.h>
79 return -EAGAIN; in r535_rpc_status_to_errno()
81 return -ENOMEM; in r535_rpc_status_to_errno()
83 return -EINVAL; in r535_rpc_status_to_errno()
91 u32 size, rptr = *gsp->msgq.rptr; in r535_gsp_msgq_wait()
97 if (WARN_ON(!size || size >= gsp->msgq.cnt)) in r535_gsp_msgq_wait()
98 return ERR_PTR(-EINVAL); in r535_gsp_msgq_wait()
101 u32 wptr = *gsp->msgq.wptr; in r535_gsp_msgq_wait()
103 used = wptr + gsp->msgq.cnt - rptr; in r535_gsp_msgq_wait()
104 if (used >= gsp->msgq.cnt) in r535_gsp_msgq_wait()
105 used -= gsp->msgq.cnt; in r535_gsp_msgq_wait()
106 if (used >= size) in r535_gsp_msgq_wait()
110 } while (--(*ptime)); in r535_gsp_msgq_wait()
112 if (WARN_ON(!*ptime)) in r535_gsp_msgq_wait()
113 return ERR_PTR(-ETIMEDOUT); in r535_gsp_msgq_wait()
115 mqe = (void *)((u8 *)gsp->shm.msgq.ptr + 0x1000 + rptr * 0x1000); in r535_gsp_msgq_wait()
117 if (prepc) { in r535_gsp_msgq_wait()
118 *prepc = (used * GSP_PAGE_SIZE) - sizeof(*mqe); in r535_gsp_msgq_wait()
119 return mqe->data; in r535_gsp_msgq_wait()
123 if (!msg) in r535_gsp_msgq_wait()
124 return ERR_PTR(-ENOMEM); in r535_gsp_msgq_wait()
126 len = ((gsp->msgq.cnt - rptr) * GSP_PAGE_SIZE) - sizeof(*mqe); in r535_gsp_msgq_wait()
128 memcpy(msg, mqe->data, len); in r535_gsp_msgq_wait()
131 if (rptr == gsp->msgq.cnt) in r535_gsp_msgq_wait()
134 repc -= len; in r535_gsp_msgq_wait()
136 if (repc) { in r535_gsp_msgq_wait()
137 mqe = (void *)((u8 *)gsp->shm.msgq.ptr + 0x1000 + 0 * 0x1000); in r535_gsp_msgq_wait()
144 (*gsp->msgq.rptr) = rptr; in r535_gsp_msgq_wait()
159 u32 argc = cmd->checksum; in r535_gsp_cmdq_push()
170 cmd->pad = 0; in r535_gsp_cmdq_push()
171 cmd->checksum = 0; in r535_gsp_cmdq_push()
172 cmd->sequence = gsp->cmdq.seq++; in r535_gsp_cmdq_push()
173 cmd->elem_count = DIV_ROUND_UP(argc, 0x1000); in r535_gsp_cmdq_push()
178 cmd->checksum = upper_32_bits(csum) ^ lower_32_bits(csum); in r535_gsp_cmdq_push()
180 wptr = *gsp->cmdq.wptr; in r535_gsp_cmdq_push()
183 free = *gsp->cmdq.rptr + gsp->cmdq.cnt - wptr - 1; in r535_gsp_cmdq_push()
184 if (free >= gsp->cmdq.cnt) in r535_gsp_cmdq_push()
185 free -= gsp->cmdq.cnt; in r535_gsp_cmdq_push()
186 if (free >= 1) in r535_gsp_cmdq_push()
190 } while(--time); in r535_gsp_cmdq_push()
192 if (WARN_ON(!time)) { in r535_gsp_cmdq_push()
194 return -ETIMEDOUT; in r535_gsp_cmdq_push()
197 cqe = (void *)((u8 *)gsp->shm.cmdq.ptr + 0x1000 + wptr * 0x1000); in r535_gsp_cmdq_push()
198 size = min_t(u32, argc, (gsp->cmdq.cnt - wptr) * GSP_PAGE_SIZE); in r535_gsp_cmdq_push()
202 if (wptr == gsp->cmdq.cnt) in r535_gsp_cmdq_push()
206 argc -= size; in r535_gsp_cmdq_push()
209 nvkm_trace(&gsp->subdev, "cmdq: wptr %d\n", wptr); in r535_gsp_cmdq_push()
211 (*gsp->cmdq.wptr) = wptr; in r535_gsp_cmdq_push()
214 nvkm_falcon_wr32(&gsp->falcon, 0xc00, 0x00000000); in r535_gsp_cmdq_push()
228 if (!cmd) in r535_gsp_cmdq_get()
229 return ERR_PTR(-ENOMEM); in r535_gsp_cmdq_get()
231 cmd->checksum = argc; in r535_gsp_cmdq_get()
232 return cmd->data; in r535_gsp_cmdq_get()
259 if (gsp->subdev.debug >= lvl) { in r535_gsp_msg_dump()
260 nvkm_printk__(&gsp->subdev, lvl, info, in r535_gsp_msg_dump()
262 msg->function, msg->length, msg->length - sizeof(*msg), in r535_gsp_msg_dump()
263 msg->rpc_result, msg->rpc_result_private); in r535_gsp_msg_dump()
265 msg->data, msg->length - sizeof(*msg), true); in r535_gsp_msg_dump()
272 struct nvkm_subdev *subdev = &gsp->subdev; in r535_gsp_msg_recv()
279 if (IS_ERR_OR_NULL(msg)) in r535_gsp_msg_recv()
282 msg = r535_gsp_msgq_recv(gsp, msg->length, &time); in r535_gsp_msg_recv()
283 if (IS_ERR_OR_NULL(msg)) in r535_gsp_msg_recv()
286 if (msg->rpc_result) { in r535_gsp_msg_recv()
289 return ERR_PTR(-EINVAL); in r535_gsp_msg_recv()
294 if (fn && msg->function == fn) { in r535_gsp_msg_recv()
295 if (repc) { in r535_gsp_msg_recv()
296 if (msg->length < sizeof(*msg) + repc) { in r535_gsp_msg_recv()
298 msg->length, sizeof(*msg) + repc); in r535_gsp_msg_recv()
301 return ERR_PTR(-EIO); in r535_gsp_msg_recv()
311 for (i = 0; i < gsp->msgq.ntfy_nr; i++) { in r535_gsp_msg_recv()
312 struct nvkm_gsp_msgq_ntfy *ntfy = &gsp->msgq.ntfy[i]; in r535_gsp_msg_recv()
314 if (ntfy->fn == msg->function) { in r535_gsp_msg_recv()
315 if (ntfy->func) in r535_gsp_msg_recv()
316 ntfy->func(ntfy->priv, ntfy->fn, msg->data, msg->length - sizeof(*msg)); in r535_gsp_msg_recv()
321 if (i == gsp->msgq.ntfy_nr) in r535_gsp_msg_recv()
325 if (fn) in r535_gsp_msg_recv()
328 if (*gsp->msgq.rptr != *gsp->msgq.wptr) in r535_gsp_msg_recv()
339 mutex_lock(&gsp->msgq.mutex); in r535_gsp_msg_ntfy_add()
340 if (WARN_ON(gsp->msgq.ntfy_nr >= ARRAY_SIZE(gsp->msgq.ntfy))) { in r535_gsp_msg_ntfy_add()
341 ret = -ENOSPC; in r535_gsp_msg_ntfy_add()
343 gsp->msgq.ntfy[gsp->msgq.ntfy_nr].fn = fn; in r535_gsp_msg_ntfy_add()
344 gsp->msgq.ntfy[gsp->msgq.ntfy_nr].func = func; in r535_gsp_msg_ntfy_add()
345 gsp->msgq.ntfy[gsp->msgq.ntfy_nr].priv = priv; in r535_gsp_msg_ntfy_add()
346 gsp->msgq.ntfy_nr++; in r535_gsp_msg_ntfy_add()
348 mutex_unlock(&gsp->msgq.mutex); in r535_gsp_msg_ntfy_add()
357 mutex_lock(&gsp->cmdq.mutex); in r535_gsp_rpc_poll()
359 mutex_unlock(&gsp->cmdq.mutex); in r535_gsp_rpc_poll()
360 if (IS_ERR(repv)) in r535_gsp_rpc_poll()
369 struct nvfw_gsp_rpc *rpc = container_of(argv, typeof(*rpc), data); in r535_gsp_rpc_send() local
371 u32 fn = rpc->function; in r535_gsp_rpc_send()
375 if (gsp->subdev.debug >= NV_DBG_TRACE) { in r535_gsp_rpc_send()
376 nvkm_trace(&gsp->subdev, "rpc fn:%d len:0x%x/0x%zx\n", rpc->function, in r535_gsp_rpc_send()
377 rpc->length, rpc->length - sizeof(*rpc)); in r535_gsp_rpc_send()
378 print_hex_dump(KERN_INFO, "rpc: ", DUMP_PREFIX_OFFSET, 16, 1, in r535_gsp_rpc_send()
379 rpc->data, rpc->length - sizeof(*rpc), true); in r535_gsp_rpc_send()
382 ret = r535_gsp_cmdq_push(gsp, rpc); in r535_gsp_rpc_send()
383 if (ret) in r535_gsp_rpc_send()
386 if (wait) { in r535_gsp_rpc_send()
388 if (!IS_ERR_OR_NULL(msg)) in r535_gsp_rpc_send()
389 repv = msg->data; in r535_gsp_rpc_send()
400 struct nvkm_gsp_device *device = event->device; in r535_gsp_event_dtor()
401 struct nvkm_gsp_client *client = device->object.client; in r535_gsp_event_dtor()
402 struct nvkm_gsp *gsp = client->gsp; in r535_gsp_event_dtor()
404 mutex_lock(&gsp->client_id.mutex); in r535_gsp_event_dtor()
405 if (event->func) { in r535_gsp_event_dtor()
406 list_del(&event->head); in r535_gsp_event_dtor()
407 event->func = NULL; in r535_gsp_event_dtor()
409 mutex_unlock(&gsp->client_id.mutex); in r535_gsp_event_dtor()
411 nvkm_gsp_rm_free(&event->object); in r535_gsp_event_dtor()
412 event->device = NULL; in r535_gsp_event_dtor()
418 struct nvkm_gsp_device *device = event->device; in r535_gsp_device_event_get()
421 ctrl = nvkm_gsp_rm_ctrl_get(&device->subdevice, in r535_gsp_device_event_get()
423 if (IS_ERR(ctrl)) in r535_gsp_device_event_get()
426 ctrl->event = event->id; in r535_gsp_device_event_get()
427 ctrl->action = NV2080_CTRL_EVENT_SET_NOTIFICATION_ACTION_REPEAT; in r535_gsp_device_event_get()
428 return nvkm_gsp_rm_ctrl_wr(&device->subdevice, ctrl); in r535_gsp_device_event_get()
435 struct nvkm_gsp_client *client = device->object.client; in r535_gsp_device_event_ctor()
436 struct nvkm_gsp *gsp = client->gsp; in r535_gsp_device_event_ctor()
440 args = nvkm_gsp_rm_alloc_get(&device->subdevice, handle, in r535_gsp_device_event_ctor()
442 &event->object); in r535_gsp_device_event_ctor()
443 if (IS_ERR(args)) in r535_gsp_device_event_ctor()
446 args->hParentClient = client->object.handle; in r535_gsp_device_event_ctor()
447 args->hSrcResource = 0; in r535_gsp_device_event_ctor()
448 args->hClass = NV01_EVENT_KERNEL_CALLBACK_EX; in r535_gsp_device_event_ctor()
449 args->notifyIndex = NV01_EVENT_CLIENT_RM | id; in r535_gsp_device_event_ctor()
450 args->data = NULL; in r535_gsp_device_event_ctor()
452 ret = nvkm_gsp_rm_alloc_wr(&event->object, args); in r535_gsp_device_event_ctor()
453 if (ret) in r535_gsp_device_event_ctor()
456 event->device = device; in r535_gsp_device_event_ctor()
457 event->id = id; in r535_gsp_device_event_ctor()
460 if (ret) { in r535_gsp_device_event_ctor()
465 mutex_lock(&gsp->client_id.mutex); in r535_gsp_device_event_ctor()
466 event->func = func; in r535_gsp_device_event_ctor()
467 list_add(&event->head, &client->events); in r535_gsp_device_event_ctor()
468 mutex_unlock(&gsp->client_id.mutex); in r535_gsp_device_event_ctor()
475 nvkm_gsp_rm_free(&device->subdevice); in r535_gsp_device_dtor()
476 nvkm_gsp_rm_free(&device->object); in r535_gsp_device_dtor()
484 return nvkm_gsp_rm_alloc(&device->object, 0x5d1d0000, NV20_SUBDEVICE_0, sizeof(*args), in r535_gsp_subdevice_ctor()
485 &device->subdevice); in r535_gsp_subdevice_ctor()
494 args = nvkm_gsp_rm_alloc_get(&client->object, 0xde1d0000, NV01_DEVICE_0, sizeof(*args), in r535_gsp_device_ctor()
495 &device->object); in r535_gsp_device_ctor()
496 if (IS_ERR(args)) in r535_gsp_device_ctor()
499 args->hClientShare = client->object.handle; in r535_gsp_device_ctor()
501 ret = nvkm_gsp_rm_alloc_wr(&device->object, args); in r535_gsp_device_ctor()
502 if (ret) in r535_gsp_device_ctor()
506 if (ret) in r535_gsp_device_ctor()
507 nvkm_gsp_rm_free(&device->object); in r535_gsp_device_ctor()
515 struct nvkm_gsp *gsp = client->gsp; in r535_gsp_client_dtor()
517 nvkm_gsp_rm_free(&client->object); in r535_gsp_client_dtor()
519 mutex_lock(&gsp->client_id.mutex); in r535_gsp_client_dtor()
520 idr_remove(&gsp->client_id.idr, client->object.handle & 0xffff); in r535_gsp_client_dtor()
521 mutex_unlock(&gsp->client_id.mutex); in r535_gsp_client_dtor()
523 client->gsp = NULL; in r535_gsp_client_dtor()
532 mutex_lock(&gsp->client_id.mutex); in r535_gsp_client_ctor()
533 ret = idr_alloc(&gsp->client_id.idr, client, 0, 0xffff + 1, GFP_KERNEL); in r535_gsp_client_ctor()
534 mutex_unlock(&gsp->client_id.mutex); in r535_gsp_client_ctor()
535 if (ret < 0) in r535_gsp_client_ctor()
538 client->gsp = gsp; in r535_gsp_client_ctor()
539 client->object.client = client; in r535_gsp_client_ctor()
540 INIT_LIST_HEAD(&client->events); in r535_gsp_client_ctor()
542 args = nvkm_gsp_rm_alloc_get(&client->object, 0xc1d00000 | ret, NV01_ROOT, sizeof(*args), in r535_gsp_client_ctor()
543 &client->object); in r535_gsp_client_ctor()
544 if (IS_ERR(args)) { in r535_gsp_client_ctor()
549 args->hClient = client->object.handle; in r535_gsp_client_ctor()
550 args->processID = ~0; in r535_gsp_client_ctor()
552 ret = nvkm_gsp_rm_alloc_wr(&client->object, args); in r535_gsp_client_ctor()
553 if (ret) { in r535_gsp_client_ctor()
564 struct nvkm_gsp_client *client = object->client; in r535_gsp_rpc_rm_free()
565 struct nvkm_gsp *gsp = client->gsp; in r535_gsp_rpc_rm_free()
566 rpc_free_v03_00 *rpc; in r535_gsp_rpc_rm_free() local
568 nvkm_debug(&gsp->subdev, "cli:0x%08x obj:0x%08x free\n", in r535_gsp_rpc_rm_free()
569 client->object.handle, object->handle); in r535_gsp_rpc_rm_free()
571 rpc = nvkm_gsp_rpc_get(gsp, NV_VGPU_MSG_FUNCTION_FREE, sizeof(*rpc)); in r535_gsp_rpc_rm_free()
572 if (WARN_ON(IS_ERR_OR_NULL(rpc))) in r535_gsp_rpc_rm_free()
573 return -EIO; in r535_gsp_rpc_rm_free()
575 rpc->params.hRoot = client->object.handle; in r535_gsp_rpc_rm_free()
576 rpc->params.hObjectParent = 0; in r535_gsp_rpc_rm_free()
577 rpc->params.hObjectOld = object->handle; in r535_gsp_rpc_rm_free()
578 return nvkm_gsp_rpc_wr(gsp, rpc, true); in r535_gsp_rpc_rm_free()
584 rpc_gsp_rm_alloc_v03_00 *rpc = container_of(repv, typeof(*rpc), params); in r535_gsp_rpc_rm_alloc_done() local
586 nvkm_gsp_rpc_done(object->client->gsp, rpc); in r535_gsp_rpc_rm_alloc_done()
592 rpc_gsp_rm_alloc_v03_00 *rpc = container_of(argv, typeof(*rpc), params); in r535_gsp_rpc_rm_alloc_push() local
593 struct nvkm_gsp *gsp = object->client->gsp; in r535_gsp_rpc_rm_alloc_push()
596 rpc = nvkm_gsp_rpc_push(gsp, rpc, true, sizeof(*rpc) + repc); in r535_gsp_rpc_rm_alloc_push()
597 if (IS_ERR_OR_NULL(rpc)) in r535_gsp_rpc_rm_alloc_push()
598 return rpc; in r535_gsp_rpc_rm_alloc_push()
600 if (rpc->status) { in r535_gsp_rpc_rm_alloc_push()
601 ret = ERR_PTR(r535_rpc_status_to_errno(rpc->status)); in r535_gsp_rpc_rm_alloc_push()
602 if (PTR_ERR(ret) != -EAGAIN) in r535_gsp_rpc_rm_alloc_push()
603 nvkm_error(&gsp->subdev, "RM_ALLOC: 0x%x\n", rpc->status); in r535_gsp_rpc_rm_alloc_push()
605 ret = repc ? rpc->params : NULL; in r535_gsp_rpc_rm_alloc_push()
608 nvkm_gsp_rpc_done(gsp, rpc); in r535_gsp_rpc_rm_alloc_push()
616 struct nvkm_gsp_client *client = object->client; in r535_gsp_rpc_rm_alloc_get()
617 struct nvkm_gsp *gsp = client->gsp; in r535_gsp_rpc_rm_alloc_get()
618 rpc_gsp_rm_alloc_v03_00 *rpc; in r535_gsp_rpc_rm_alloc_get() local
620 nvkm_debug(&gsp->subdev, "cli:0x%08x obj:0x%08x new obj:0x%08x cls:0x%08x argc:%d\n", in r535_gsp_rpc_rm_alloc_get()
621 client->object.handle, object->parent->handle, object->handle, oclass, argc); in r535_gsp_rpc_rm_alloc_get()
623 rpc = nvkm_gsp_rpc_get(gsp, NV_VGPU_MSG_FUNCTION_GSP_RM_ALLOC, sizeof(*rpc) + argc); in r535_gsp_rpc_rm_alloc_get()
624 if (IS_ERR(rpc)) in r535_gsp_rpc_rm_alloc_get()
625 return rpc; in r535_gsp_rpc_rm_alloc_get()
627 rpc->hClient = client->object.handle; in r535_gsp_rpc_rm_alloc_get()
628 rpc->hParent = object->parent->handle; in r535_gsp_rpc_rm_alloc_get()
629 rpc->hObject = object->handle; in r535_gsp_rpc_rm_alloc_get()
630 rpc->hClass = oclass; in r535_gsp_rpc_rm_alloc_get()
631 rpc->status = 0; in r535_gsp_rpc_rm_alloc_get()
632 rpc->paramsSize = argc; in r535_gsp_rpc_rm_alloc_get()
633 return rpc->params; in r535_gsp_rpc_rm_alloc_get()
639 rpc_gsp_rm_control_v03_00 *rpc = container_of(repv, typeof(*rpc), params); in r535_gsp_rpc_rm_ctrl_done() local
641 if (!repv) in r535_gsp_rpc_rm_ctrl_done()
643 nvkm_gsp_rpc_done(object->client->gsp, rpc); in r535_gsp_rpc_rm_ctrl_done()
649 rpc_gsp_rm_control_v03_00 *rpc = container_of((*argv), typeof(*rpc), params); in r535_gsp_rpc_rm_ctrl_push() local
650 struct nvkm_gsp *gsp = object->client->gsp; in r535_gsp_rpc_rm_ctrl_push()
653 rpc = nvkm_gsp_rpc_push(gsp, rpc, true, repc); in r535_gsp_rpc_rm_ctrl_push()
654 if (IS_ERR_OR_NULL(rpc)) { in r535_gsp_rpc_rm_ctrl_push()
656 return PTR_ERR(rpc); in r535_gsp_rpc_rm_ctrl_push()
659 if (rpc->status) { in r535_gsp_rpc_rm_ctrl_push()
660 ret = r535_rpc_status_to_errno(rpc->status); in r535_gsp_rpc_rm_ctrl_push()
661 if (ret != -EAGAIN) in r535_gsp_rpc_rm_ctrl_push()
662 nvkm_error(&gsp->subdev, "cli:0x%08x obj:0x%08x ctrl cmd:0x%08x failed: 0x%08x\n", in r535_gsp_rpc_rm_ctrl_push()
663 object->client->object.handle, object->handle, rpc->cmd, rpc->status); in r535_gsp_rpc_rm_ctrl_push()
666 if (repc) in r535_gsp_rpc_rm_ctrl_push()
667 *argv = rpc->params; in r535_gsp_rpc_rm_ctrl_push()
669 nvkm_gsp_rpc_done(gsp, rpc); in r535_gsp_rpc_rm_ctrl_push()
677 struct nvkm_gsp_client *client = object->client; in r535_gsp_rpc_rm_ctrl_get()
678 struct nvkm_gsp *gsp = client->gsp; in r535_gsp_rpc_rm_ctrl_get()
679 rpc_gsp_rm_control_v03_00 *rpc; in r535_gsp_rpc_rm_ctrl_get() local
681 nvkm_debug(&gsp->subdev, "cli:0x%08x obj:0x%08x ctrl cmd:0x%08x argc:%d\n", in r535_gsp_rpc_rm_ctrl_get()
682 client->object.handle, object->handle, cmd, argc); in r535_gsp_rpc_rm_ctrl_get()
684 rpc = nvkm_gsp_rpc_get(gsp, NV_VGPU_MSG_FUNCTION_GSP_RM_CONTROL, sizeof(*rpc) + argc); in r535_gsp_rpc_rm_ctrl_get()
685 if (IS_ERR(rpc)) in r535_gsp_rpc_rm_ctrl_get()
686 return rpc; in r535_gsp_rpc_rm_ctrl_get()
688 rpc->hClient = client->object.handle; in r535_gsp_rpc_rm_ctrl_get()
689 rpc->hObject = object->handle; in r535_gsp_rpc_rm_ctrl_get()
690 rpc->cmd = cmd; in r535_gsp_rpc_rm_ctrl_get()
691 rpc->status = 0; in r535_gsp_rpc_rm_ctrl_get()
692 rpc->paramsSize = argc; in r535_gsp_rpc_rm_ctrl_get()
693 return rpc->params; in r535_gsp_rpc_rm_ctrl_get()
699 struct nvfw_gsp_rpc *rpc = container_of(repv, typeof(*rpc), data); in r535_gsp_rpc_done() local
701 r535_gsp_msg_done(gsp, rpc); in r535_gsp_rpc_done()
707 struct nvfw_gsp_rpc *rpc; in r535_gsp_rpc_get() local
709 rpc = r535_gsp_cmdq_get(gsp, ALIGN(sizeof(*rpc) + argc, sizeof(u64))); in r535_gsp_rpc_get()
710 if (IS_ERR(rpc)) in r535_gsp_rpc_get()
711 return ERR_CAST(rpc); in r535_gsp_rpc_get()
713 rpc->header_version = 0x03000000; in r535_gsp_rpc_get()
714 rpc->signature = ('C' << 24) | ('P' << 16) | ('R' << 8) | 'V'; in r535_gsp_rpc_get()
715 rpc->function = fn; in r535_gsp_rpc_get()
716 rpc->rpc_result = 0xffffffff; in r535_gsp_rpc_get()
717 rpc->rpc_result_private = 0xffffffff; in r535_gsp_rpc_get()
718 rpc->length = sizeof(*rpc) + argc; in r535_gsp_rpc_get()
719 return rpc->data; in r535_gsp_rpc_get()
725 struct nvfw_gsp_rpc *rpc = container_of(argv, typeof(*rpc), data); in r535_gsp_rpc_push() local
726 struct r535_gsp_msg *cmd = container_of((void *)rpc, typeof(*cmd), data); in r535_gsp_rpc_push()
727 const u32 max_msg_size = (16 * 0x1000) - sizeof(struct r535_gsp_msg); in r535_gsp_rpc_push()
728 const u32 max_rpc_size = max_msg_size - sizeof(*rpc); in r535_gsp_rpc_push()
729 u32 rpc_size = rpc->length - sizeof(*rpc); in r535_gsp_rpc_push()
732 mutex_lock(&gsp->cmdq.mutex); in r535_gsp_rpc_push()
733 if (rpc_size > max_rpc_size) { in r535_gsp_rpc_push()
734 const u32 fn = rpc->function; in r535_gsp_rpc_push()
736 /* Adjust length, and send initial RPC. */ in r535_gsp_rpc_push()
737 rpc->length = sizeof(*rpc) + max_rpc_size; in r535_gsp_rpc_push()
738 cmd->checksum = rpc->length; in r535_gsp_rpc_push()
741 if (IS_ERR(repv)) in r535_gsp_rpc_push()
745 rpc_size -= max_rpc_size; in r535_gsp_rpc_push()
753 if (IS_ERR(next)) { in r535_gsp_rpc_push()
761 if (IS_ERR(repv)) in r535_gsp_rpc_push()
765 rpc_size -= size; in r535_gsp_rpc_push()
769 if (wait) { in r535_gsp_rpc_push()
770 rpc = r535_gsp_msg_recv(gsp, fn, repc); in r535_gsp_rpc_push()
771 if (!IS_ERR_OR_NULL(rpc)) in r535_gsp_rpc_push()
772 repv = rpc->data; in r535_gsp_rpc_push()
774 repv = rpc; in r535_gsp_rpc_push()
783 mutex_unlock(&gsp->cmdq.mutex); in r535_gsp_rpc_push()
818 mutex_lock(&gsp->cmdq.mutex); in r535_gsp_msgq_work()
819 if (*gsp->msgq.rptr != *gsp->msgq.wptr) in r535_gsp_msgq_work()
821 mutex_unlock(&gsp->cmdq.mutex); in r535_gsp_msgq_work()
828 struct nvkm_subdev *subdev = &gsp->subdev; in r535_gsp_intr()
829 u32 intr = nvkm_falcon_rd32(&gsp->falcon, 0x0008); in r535_gsp_intr()
830 u32 inte = nvkm_falcon_rd32(&gsp->falcon, gsp->falcon.func->addr2 + in r535_gsp_intr()
831 gsp->falcon.func->riscv_irqmask); in r535_gsp_intr()
834 if (!stat) { in r535_gsp_intr()
839 if (stat & 0x00000040) { in r535_gsp_intr()
840 nvkm_falcon_wr32(&gsp->falcon, 0x004, 0x00000040); in r535_gsp_intr()
841 schedule_work(&gsp->msgq.work); in r535_gsp_intr()
845 if (stat) { in r535_gsp_intr()
847 nvkm_falcon_wr32(&gsp->falcon, 0x014, stat); in r535_gsp_intr()
848 nvkm_falcon_wr32(&gsp->falcon, 0x004, stat); in r535_gsp_intr()
851 nvkm_falcon_intr_retrigger(&gsp->falcon); in r535_gsp_intr()
861 ctrl = nvkm_gsp_rm_ctrl_get(&gsp->internal.device.subdevice, in r535_gsp_intr_get_table()
863 if (IS_ERR(ctrl)) in r535_gsp_intr_get_table()
866 ret = nvkm_gsp_rm_ctrl_push(&gsp->internal.device.subdevice, &ctrl, sizeof(*ctrl)); in r535_gsp_intr_get_table()
867 if (WARN_ON(ret)) { in r535_gsp_intr_get_table()
868 nvkm_gsp_rm_ctrl_done(&gsp->internal.device.subdevice, ctrl); in r535_gsp_intr_get_table()
872 for (unsigned i = 0; i < ctrl->tableLen; i++) { in r535_gsp_intr_get_table()
876 nvkm_debug(&gsp->subdev, in r535_gsp_intr_get_table()
878 ctrl->table[i].engineIdx, ctrl->table[i].pmcIntrMask, in r535_gsp_intr_get_table()
879 ctrl->table[i].vectorStall, ctrl->table[i].vectorNonStall); in r535_gsp_intr_get_table()
881 switch (ctrl->table[i].engineIdx) { in r535_gsp_intr_get_table()
892 inst = ctrl->table[i].engineIdx - MC_ENGINE_IDX_CE0; in r535_gsp_intr_get_table()
900 inst = ctrl->table[i].engineIdx - MC_ENGINE_IDX_NVDEC0; in r535_gsp_intr_get_table()
904 inst = ctrl->table[i].engineIdx - MC_ENGINE_IDX_MSENC; in r535_gsp_intr_get_table()
908 inst = ctrl->table[i].engineIdx - MC_ENGINE_IDX_NVJPEG0; in r535_gsp_intr_get_table()
918 if (WARN_ON(gsp->intr_nr == ARRAY_SIZE(gsp->intr))) { in r535_gsp_intr_get_table()
919 ret = -ENOSPC; in r535_gsp_intr_get_table()
923 gsp->intr[gsp->intr_nr].type = type; in r535_gsp_intr_get_table()
924 gsp->intr[gsp->intr_nr].inst = inst; in r535_gsp_intr_get_table()
925 gsp->intr[gsp->intr_nr].stall = ctrl->table[i].vectorStall; in r535_gsp_intr_get_table()
926 gsp->intr[gsp->intr_nr].nonstall = ctrl->table[i].vectorNonStall; in r535_gsp_intr_get_table()
927 gsp->intr_nr++; in r535_gsp_intr_get_table()
930 nvkm_gsp_rm_ctrl_done(&gsp->internal.device.subdevice, ctrl); in r535_gsp_intr_get_table()
937 GspStaticConfigInfo *rpc; in r535_gsp_rpc_get_gsp_static_info() local
938 int last_usable = -1; in r535_gsp_rpc_get_gsp_static_info()
940 rpc = nvkm_gsp_rpc_rd(gsp, NV_VGPU_MSG_FUNCTION_GET_GSP_STATIC_INFO, sizeof(*rpc)); in r535_gsp_rpc_get_gsp_static_info()
941 if (IS_ERR(rpc)) in r535_gsp_rpc_get_gsp_static_info()
942 return PTR_ERR(rpc); in r535_gsp_rpc_get_gsp_static_info()
944 gsp->internal.client.object.client = &gsp->internal.client; in r535_gsp_rpc_get_gsp_static_info()
945 gsp->internal.client.object.parent = NULL; in r535_gsp_rpc_get_gsp_static_info()
946 gsp->internal.client.object.handle = rpc->hInternalClient; in r535_gsp_rpc_get_gsp_static_info()
947 gsp->internal.client.gsp = gsp; in r535_gsp_rpc_get_gsp_static_info()
949 gsp->internal.device.object.client = &gsp->internal.client; in r535_gsp_rpc_get_gsp_static_info()
950 gsp->internal.device.object.parent = &gsp->internal.client.object; in r535_gsp_rpc_get_gsp_static_info()
951 gsp->internal.device.object.handle = rpc->hInternalDevice; in r535_gsp_rpc_get_gsp_static_info()
953 gsp->internal.device.subdevice.client = &gsp->internal.client; in r535_gsp_rpc_get_gsp_static_info()
954 gsp->internal.device.subdevice.parent = &gsp->internal.device.object; in r535_gsp_rpc_get_gsp_static_info()
955 gsp->internal.device.subdevice.handle = rpc->hInternalSubdevice; in r535_gsp_rpc_get_gsp_static_info()
957 gsp->bar.rm_bar1_pdb = rpc->bar1PdeBase; in r535_gsp_rpc_get_gsp_static_info()
958 gsp->bar.rm_bar2_pdb = rpc->bar2PdeBase; in r535_gsp_rpc_get_gsp_static_info()
960 for (int i = 0; i < rpc->fbRegionInfoParams.numFBRegions; i++) { in r535_gsp_rpc_get_gsp_static_info()
962 &rpc->fbRegionInfoParams.fbRegion[i]; in r535_gsp_rpc_get_gsp_static_info()
964 nvkm_debug(&gsp->subdev, "fb region %d: " in r535_gsp_rpc_get_gsp_static_info()
965 "%016llx-%016llx rsvd:%016llx perf:%08x comp:%d iso:%d prot:%d\n", i, in r535_gsp_rpc_get_gsp_static_info()
966 reg->base, reg->limit, reg->reserved, reg->performance, in r535_gsp_rpc_get_gsp_static_info()
967 reg->supportCompressed, reg->supportISO, reg->bProtected); in r535_gsp_rpc_get_gsp_static_info()
969 if (!reg->reserved && !reg->bProtected) { in r535_gsp_rpc_get_gsp_static_info()
970 if (reg->supportCompressed && reg->supportISO && in r535_gsp_rpc_get_gsp_static_info()
971 !WARN_ON_ONCE(gsp->fb.region_nr >= ARRAY_SIZE(gsp->fb.region))) { in r535_gsp_rpc_get_gsp_static_info()
972 const u64 size = (reg->limit + 1) - reg->base; in r535_gsp_rpc_get_gsp_static_info()
974 gsp->fb.region[gsp->fb.region_nr].addr = reg->base; in r535_gsp_rpc_get_gsp_static_info()
975 gsp->fb.region[gsp->fb.region_nr].size = size; in r535_gsp_rpc_get_gsp_static_info()
976 gsp->fb.region_nr++; in r535_gsp_rpc_get_gsp_static_info()
983 if (last_usable >= 0) { in r535_gsp_rpc_get_gsp_static_info()
984 u32 rsvd_base = rpc->fbRegionInfoParams.fbRegion[last_usable].limit + 1; in r535_gsp_rpc_get_gsp_static_info()
986 gsp->fb.rsvd_size = gsp->fb.heap.addr - rsvd_base; in r535_gsp_rpc_get_gsp_static_info()
989 for (int gpc = 0; gpc < ARRAY_SIZE(rpc->tpcInfo); gpc++) { in r535_gsp_rpc_get_gsp_static_info()
990 if (rpc->gpcInfo.gpcMask & BIT(gpc)) { in r535_gsp_rpc_get_gsp_static_info()
991 gsp->gr.tpcs += hweight32(rpc->tpcInfo[gpc].tpcMask); in r535_gsp_rpc_get_gsp_static_info()
992 gsp->gr.gpcs++; in r535_gsp_rpc_get_gsp_static_info()
996 nvkm_gsp_rpc_done(gsp, rpc); in r535_gsp_rpc_get_gsp_static_info()
1003 if (mem->data) { in nvkm_gsp_mem_dtor()
1006 * GSP-RM if the buffer was prematurely freed. in nvkm_gsp_mem_dtor()
1008 memset(mem->data, 0xFF, mem->size); in nvkm_gsp_mem_dtor()
1010 dma_free_coherent(gsp->subdev.device->dev, mem->size, mem->data, mem->addr); in nvkm_gsp_mem_dtor()
1018 mem->size = size; in nvkm_gsp_mem_ctor()
1019 mem->data = dma_alloc_coherent(gsp->subdev.device->dev, size, &mem->addr, GFP_KERNEL); in nvkm_gsp_mem_ctor()
1020 if (WARN_ON(!mem->data)) in nvkm_gsp_mem_ctor()
1021 return -ENOMEM; in nvkm_gsp_mem_ctor()
1029 struct nvkm_device *device = gsp->subdev.device; in r535_gsp_postinit()
1033 if (WARN_ON(ret)) in r535_gsp_postinit()
1036 INIT_WORK(&gsp->msgq.work, r535_gsp_msgq_work); in r535_gsp_postinit()
1039 if (WARN_ON(ret)) in r535_gsp_postinit()
1042 ret = nvkm_gsp_intr_stall(gsp, gsp->subdev.type, gsp->subdev.inst); in r535_gsp_postinit()
1043 if (WARN_ON(ret < 0)) in r535_gsp_postinit()
1046 ret = nvkm_inth_add(&device->vfn->intr, ret, NVKM_INTR_PRIO_NORMAL, &gsp->subdev, in r535_gsp_postinit()
1047 r535_gsp_intr, &gsp->subdev.inth); in r535_gsp_postinit()
1048 if (WARN_ON(ret)) in r535_gsp_postinit()
1051 nvkm_inth_allow(&gsp->subdev.inth); in r535_gsp_postinit()
1055 nvkm_gsp_mem_dtor(gsp, &gsp->boot.fw); in r535_gsp_postinit()
1056 nvkm_gsp_mem_dtor(gsp, &gsp->libos); in r535_gsp_postinit()
1064 rpc_unloading_guest_driver_v1F_07 *rpc; in r535_gsp_rpc_unloading_guest_driver() local
1066 rpc = nvkm_gsp_rpc_get(gsp, NV_VGPU_MSG_FUNCTION_UNLOADING_GUEST_DRIVER, sizeof(*rpc)); in r535_gsp_rpc_unloading_guest_driver()
1067 if (IS_ERR(rpc)) in r535_gsp_rpc_unloading_guest_driver()
1068 return PTR_ERR(rpc); in r535_gsp_rpc_unloading_guest_driver()
1070 if (suspend) { in r535_gsp_rpc_unloading_guest_driver()
1071 rpc->bInPMTransition = 1; in r535_gsp_rpc_unloading_guest_driver()
1072 rpc->bGc6Entering = 0; in r535_gsp_rpc_unloading_guest_driver()
1073 rpc->newLevel = NV2080_CTRL_GPU_SET_POWER_STATE_GPU_LEVEL_3; in r535_gsp_rpc_unloading_guest_driver()
1075 rpc->bInPMTransition = 0; in r535_gsp_rpc_unloading_guest_driver()
1076 rpc->bGc6Entering = 0; in r535_gsp_rpc_unloading_guest_driver()
1077 rpc->newLevel = NV2080_CTRL_GPU_SET_POWER_STATE_GPU_LEVEL_0; in r535_gsp_rpc_unloading_guest_driver()
1080 return nvkm_gsp_rpc_wr(gsp, rpc, true); in r535_gsp_rpc_unloading_guest_driver()
1098 PACKED_REGISTRY_TABLE *rpc; in r535_gsp_rpc_set_registry() local
1102 size_t rpc_size = struct_size(rpc, entries, NV_GSP_REG_NUM_ENTRIES); in r535_gsp_rpc_set_registry()
1108 rpc = nvkm_gsp_rpc_get(gsp, NV_VGPU_MSG_FUNCTION_SET_REGISTRY, rpc_size); in r535_gsp_rpc_set_registry()
1109 if (IS_ERR(rpc)) in r535_gsp_rpc_set_registry()
1110 return PTR_ERR(rpc); in r535_gsp_rpc_set_registry()
1112 rpc->numEntries = NV_GSP_REG_NUM_ENTRIES; in r535_gsp_rpc_set_registry()
1114 str_offset = offsetof(typeof(*rpc), entries[NV_GSP_REG_NUM_ENTRIES]); in r535_gsp_rpc_set_registry()
1115 strings = (char *)&rpc->entries[NV_GSP_REG_NUM_ENTRIES]; in r535_gsp_rpc_set_registry()
1119 rpc->entries[i].nameOffset = str_offset; in r535_gsp_rpc_set_registry()
1120 rpc->entries[i].type = 1; in r535_gsp_rpc_set_registry()
1121 rpc->entries[i].data = r535_registry_entries[i].value; in r535_gsp_rpc_set_registry()
1122 rpc->entries[i].length = 4; in r535_gsp_rpc_set_registry()
1127 rpc->size = str_offset; in r535_gsp_rpc_set_registry()
1129 return nvkm_gsp_rpc_wr(gsp, rpc, false); in r535_gsp_rpc_set_registry()
1132 #if defined(CONFIG_ACPI) && defined(CONFIG_X86)
1146 caps->status = 0xffff; in r535_gsp_acpi_caps()
1148 if (!acpi_check_dsm(handle, &NVOP_DSM_GUID, NVOP_DSM_REV, BIT_ULL(0x1a))) in r535_gsp_acpi_caps()
1152 if (!obj) in r535_gsp_acpi_caps()
1155 if (WARN_ON(obj->type != ACPI_TYPE_BUFFER) || in r535_gsp_acpi_caps()
1156 WARN_ON(obj->buffer.length != 4)) in r535_gsp_acpi_caps()
1159 caps->status = 0; in r535_gsp_acpi_caps()
1160 caps->optimusCaps = *(u32 *)obj->buffer.pointer; in r535_gsp_acpi_caps()
1181 jt->status = 0xffff; in r535_gsp_acpi_jt()
1184 if (!obj) in r535_gsp_acpi_jt()
1187 if (WARN_ON(obj->type != ACPI_TYPE_BUFFER) || in r535_gsp_acpi_jt()
1188 WARN_ON(obj->buffer.length != 4)) in r535_gsp_acpi_jt()
1191 jt->status = 0; in r535_gsp_acpi_jt()
1192 jt->jtCaps = *(u32 *)obj->buffer.pointer; in r535_gsp_acpi_jt()
1193 jt->jtRevId = (jt->jtCaps & 0xfff00000) >> 20; in r535_gsp_acpi_jt()
1194 jt->bSBIOSCaps = 0; in r535_gsp_acpi_jt()
1211 mode->status = 0xffff; in r535_gsp_acpi_mux_id()
1212 part->status = 0xffff; in r535_gsp_acpi_mux_id()
1216 if (ACPI_FAILURE(status) || !iter) in r535_gsp_acpi_mux_id()
1220 if (ACPI_FAILURE(status) || value != id) in r535_gsp_acpi_mux_id()
1226 if (!handle_mux) in r535_gsp_acpi_mux_id()
1229 /* I -think- 0 means "acquire" according to nvidia's driver source */ in r535_gsp_acpi_mux_id()
1230 input.pointer->integer.type = ACPI_TYPE_INTEGER; in r535_gsp_acpi_mux_id()
1231 input.pointer->integer.value = 0; in r535_gsp_acpi_mux_id()
1234 if (ACPI_SUCCESS(status)) { in r535_gsp_acpi_mux_id()
1235 mode->acpiId = id; in r535_gsp_acpi_mux_id()
1236 mode->mode = value; in r535_gsp_acpi_mux_id()
1237 mode->status = 0; in r535_gsp_acpi_mux_id()
1241 if (ACPI_SUCCESS(status)) { in r535_gsp_acpi_mux_id()
1242 part->acpiId = id; in r535_gsp_acpi_mux_id()
1243 part->mode = value; in r535_gsp_acpi_mux_id()
1244 part->status = 0; in r535_gsp_acpi_mux_id()
1251 mux->tableLen = dod->acpiIdListLen / sizeof(dod->acpiIdList[0]); in r535_gsp_acpi_mux()
1253 for (int i = 0; i < mux->tableLen; i++) { in r535_gsp_acpi_mux()
1254 r535_gsp_acpi_mux_id(handle, dod->acpiIdList[i], &mux->acpiIdMuxModeTable[i], in r535_gsp_acpi_mux()
1255 &mux->acpiIdMuxPartTable[i]); in r535_gsp_acpi_mux()
1266 dod->status = 0xffff; in r535_gsp_acpi_dod()
1269 if (ACPI_FAILURE(status)) in r535_gsp_acpi_dod()
1274 if (WARN_ON(_DOD->type != ACPI_TYPE_PACKAGE) || in r535_gsp_acpi_dod()
1275 WARN_ON(_DOD->package.count > ARRAY_SIZE(dod->acpiIdList))) in r535_gsp_acpi_dod()
1278 for (int i = 0; i < _DOD->package.count; i++) { in r535_gsp_acpi_dod()
1279 if (WARN_ON(_DOD->package.elements[i].type != ACPI_TYPE_INTEGER)) in r535_gsp_acpi_dod()
1282 dod->acpiIdList[i] = _DOD->package.elements[i].integer.value; in r535_gsp_acpi_dod()
1283 dod->acpiIdListLen += sizeof(dod->acpiIdList[0]); in r535_gsp_acpi_dod()
1286 dod->status = 0; in r535_gsp_acpi_dod()
1294 #if defined(CONFIG_ACPI) && defined(CONFIG_X86) in r535_gsp_acpi_info()
1295 acpi_handle handle = ACPI_HANDLE(gsp->subdev.device->dev); in r535_gsp_acpi_info()
1297 if (!handle) in r535_gsp_acpi_info()
1300 acpi->bValid = 1; in r535_gsp_acpi_info()
1302 r535_gsp_acpi_dod(handle, &acpi->dodMethodData); in r535_gsp_acpi_info()
1303 if (acpi->dodMethodData.status == 0) in r535_gsp_acpi_info()
1304 r535_gsp_acpi_mux(handle, &acpi->dodMethodData, &acpi->muxMethodData); in r535_gsp_acpi_info()
1306 r535_gsp_acpi_jt(handle, &acpi->jtMethodData); in r535_gsp_acpi_info()
1307 r535_gsp_acpi_caps(handle, &acpi->capsMethodData); in r535_gsp_acpi_info()
1314 struct nvkm_device *device = gsp->subdev.device; in r535_gsp_rpc_set_system_info()
1318 if (WARN_ON(device->type == NVKM_DEVICE_TEGRA)) in r535_gsp_rpc_set_system_info()
1319 return -ENOSYS; in r535_gsp_rpc_set_system_info()
1322 if (IS_ERR(info)) in r535_gsp_rpc_set_system_info()
1325 info->gpuPhysAddr = device->func->resource_addr(device, 0); in r535_gsp_rpc_set_system_info()
1326 info->gpuPhysFbAddr = device->func->resource_addr(device, 1); in r535_gsp_rpc_set_system_info()
1327 info->gpuPhysInstAddr = device->func->resource_addr(device, 3); in r535_gsp_rpc_set_system_info()
1328 info->nvDomainBusDeviceFunc = pci_dev_id(pdev->pdev); in r535_gsp_rpc_set_system_info()
1329 info->maxUserVa = TASK_SIZE; in r535_gsp_rpc_set_system_info()
1330 info->pciConfigMirrorBase = 0x088000; in r535_gsp_rpc_set_system_info()
1331 info->pciConfigMirrorSize = 0x001000; in r535_gsp_rpc_set_system_info()
1332 r535_gsp_acpi_info(gsp, &info->acpiMethodData); in r535_gsp_rpc_set_system_info()
1341 struct nvkm_subdev *subdev = &gsp->subdev; in r535_gsp_msg_os_error_log()
1344 if (WARN_ON(repc < sizeof(*msg))) in r535_gsp_msg_os_error_log()
1345 return -EINVAL; in r535_gsp_msg_os_error_log()
1347 nvkm_error(subdev, "Xid:%d %s\n", msg->exceptType, msg->errString); in r535_gsp_msg_os_error_log()
1356 struct nvkm_subdev *subdev = &gsp->subdev; in r535_gsp_msg_rc_triggered()
1360 if (WARN_ON(repc < sizeof(*msg))) in r535_gsp_msg_rc_triggered()
1361 return -EINVAL; in r535_gsp_msg_rc_triggered()
1364 msg->nv2080EngineType, msg->chid, msg->exceptType, msg->scope, in r535_gsp_msg_rc_triggered()
1365 msg->partitionAttributionId); in r535_gsp_msg_rc_triggered()
1367 chan = nvkm_chan_get_chid(&subdev->device->fifo->engine, msg->chid / 8, &flags); in r535_gsp_msg_rc_triggered()
1368 if (!chan) { in r535_gsp_msg_rc_triggered()
1369 nvkm_error(subdev, "rc chid:%d not found!\n", msg->chid); in r535_gsp_msg_rc_triggered()
1382 struct nvkm_subdev *subdev = &gsp->subdev; in r535_gsp_msg_mmu_fault_queued()
1395 struct nvkm_subdev *subdev = &gsp->subdev; in r535_gsp_msg_post_event()
1398 if (WARN_ON(repc < sizeof(*msg))) in r535_gsp_msg_post_event()
1399 return -EINVAL; in r535_gsp_msg_post_event()
1400 if (WARN_ON(repc != sizeof(*msg) + msg->eventDataSize)) in r535_gsp_msg_post_event()
1401 return -EINVAL; in r535_gsp_msg_post_event()
1404 msg->hClient, msg->hEvent, msg->notifyIndex, msg->data, in r535_gsp_msg_post_event()
1405 msg->status, msg->eventDataSize, msg->bNotifyList); in r535_gsp_msg_post_event()
1407 mutex_lock(&gsp->client_id.mutex); in r535_gsp_msg_post_event()
1408 client = idr_find(&gsp->client_id.idr, msg->hClient & 0xffff); in r535_gsp_msg_post_event()
1409 if (client) { in r535_gsp_msg_post_event()
1413 list_for_each_entry(event, &client->events, head) { in r535_gsp_msg_post_event()
1414 if (event->object.handle == msg->hEvent) { in r535_gsp_msg_post_event()
1415 event->func(event, msg->eventData, msg->eventDataSize); in r535_gsp_msg_post_event()
1420 if (!handled) { in r535_gsp_msg_post_event()
1422 msg->hClient, msg->hEvent); in r535_gsp_msg_post_event()
1425 nvkm_error(subdev, "event: cid 0x%08x not found!\n", msg->hClient); in r535_gsp_msg_post_event()
1427 mutex_unlock(&gsp->client_id.mutex); in r535_gsp_msg_post_event()
1432 * r535_gsp_msg_run_cpu_sequencer() -- process I/O commands from the GSP
1436 * perform a special mid-initialization reset.
1442 struct nvkm_subdev *subdev = &gsp->subdev; in r535_gsp_msg_run_cpu_sequencer()
1443 struct nvkm_device *device = subdev->device; in r535_gsp_msg_run_cpu_sequencer()
1447 nvkm_debug(subdev, "seq: %08x %08x\n", seq->bufferSizeDWord, seq->cmdIndex); in r535_gsp_msg_run_cpu_sequencer()
1449 while (ptr < seq->cmdIndex) { in r535_gsp_msg_run_cpu_sequencer()
1450 GSP_SEQUENCER_BUFFER_CMD *cmd = (void *)&seq->commandBuffer[ptr]; in r535_gsp_msg_run_cpu_sequencer()
1453 ptr += GSP_SEQUENCER_PAYLOAD_SIZE_DWORDS(cmd->opCode); in r535_gsp_msg_run_cpu_sequencer()
1455 switch (cmd->opCode) { in r535_gsp_msg_run_cpu_sequencer()
1457 u32 addr = cmd->payload.regWrite.addr; in r535_gsp_msg_run_cpu_sequencer()
1458 u32 data = cmd->payload.regWrite.val; in r535_gsp_msg_run_cpu_sequencer()
1465 u32 addr = cmd->payload.regModify.addr; in r535_gsp_msg_run_cpu_sequencer()
1466 u32 mask = cmd->payload.regModify.mask; in r535_gsp_msg_run_cpu_sequencer()
1467 u32 data = cmd->payload.regModify.val; in r535_gsp_msg_run_cpu_sequencer()
1474 u32 addr = cmd->payload.regPoll.addr; in r535_gsp_msg_run_cpu_sequencer()
1475 u32 mask = cmd->payload.regPoll.mask; in r535_gsp_msg_run_cpu_sequencer()
1476 u32 data = cmd->payload.regPoll.val; in r535_gsp_msg_run_cpu_sequencer()
1477 u32 usec = cmd->payload.regPoll.timeout ?: 4000000; in r535_gsp_msg_run_cpu_sequencer()
1478 //u32 error = cmd->payload.regPoll.error; in r535_gsp_msg_run_cpu_sequencer()
1483 if ((nvkm_rd32(device, addr) & mask) == data) in r535_gsp_msg_run_cpu_sequencer()
1489 u32 usec = cmd->payload.delayUs.val; in r535_gsp_msg_run_cpu_sequencer()
1496 u32 addr = cmd->payload.regStore.addr; in r535_gsp_msg_run_cpu_sequencer()
1497 u32 slot = cmd->payload.regStore.index; in r535_gsp_msg_run_cpu_sequencer()
1499 seq->regSaveArea[slot] = nvkm_rd32(device, addr); in r535_gsp_msg_run_cpu_sequencer()
1500 nvkm_trace(subdev, "seq save %08x -> %d: %08x\n", addr, slot, in r535_gsp_msg_run_cpu_sequencer()
1501 seq->regSaveArea[slot]); in r535_gsp_msg_run_cpu_sequencer()
1506 nvkm_falcon_reset(&gsp->falcon); in r535_gsp_msg_run_cpu_sequencer()
1507 nvkm_falcon_mask(&gsp->falcon, 0x624, 0x00000080, 0x00000080); in r535_gsp_msg_run_cpu_sequencer()
1508 nvkm_falcon_wr32(&gsp->falcon, 0x10c, 0x00000000); in r535_gsp_msg_run_cpu_sequencer()
1512 if (nvkm_falcon_rd32(&gsp->falcon, 0x100) & 0x00000040) in r535_gsp_msg_run_cpu_sequencer()
1513 nvkm_falcon_wr32(&gsp->falcon, 0x130, 0x00000002); in r535_gsp_msg_run_cpu_sequencer()
1515 nvkm_falcon_wr32(&gsp->falcon, 0x100, 0x00000002); in r535_gsp_msg_run_cpu_sequencer()
1520 if (nvkm_falcon_rd32(&gsp->falcon, 0x100) & 0x00000010) in r535_gsp_msg_run_cpu_sequencer()
1525 struct nvkm_sec2 *sec2 = device->sec2; in r535_gsp_msg_run_cpu_sequencer()
1530 ret = gsp->func->reset(gsp); in r535_gsp_msg_run_cpu_sequencer()
1531 if (WARN_ON(ret)) in r535_gsp_msg_run_cpu_sequencer()
1534 nvkm_falcon_wr32(&gsp->falcon, 0x040, lower_32_bits(gsp->libos.addr)); in r535_gsp_msg_run_cpu_sequencer()
1535 nvkm_falcon_wr32(&gsp->falcon, 0x044, upper_32_bits(gsp->libos.addr)); in r535_gsp_msg_run_cpu_sequencer()
1537 nvkm_falcon_start(&sec2->falcon); in r535_gsp_msg_run_cpu_sequencer()
1539 if (nvkm_msec(device, 2000, in r535_gsp_msg_run_cpu_sequencer()
1540 if (nvkm_rd32(device, 0x1180f8) & 0x04000000) in r535_gsp_msg_run_cpu_sequencer()
1543 return -ETIMEDOUT; in r535_gsp_msg_run_cpu_sequencer()
1545 mbox0 = nvkm_falcon_rd32(&sec2->falcon, 0x040); in r535_gsp_msg_run_cpu_sequencer()
1546 if (WARN_ON(mbox0)) { in r535_gsp_msg_run_cpu_sequencer()
1547 nvkm_error(&gsp->subdev, "seq core resume sec2: 0x%x\n", mbox0); in r535_gsp_msg_run_cpu_sequencer()
1548 return -EIO; in r535_gsp_msg_run_cpu_sequencer()
1551 nvkm_falcon_wr32(&gsp->falcon, 0x080, gsp->boot.app_version); in r535_gsp_msg_run_cpu_sequencer()
1553 if (WARN_ON(!nvkm_falcon_riscv_active(&gsp->falcon))) in r535_gsp_msg_run_cpu_sequencer()
1554 return -EIO; in r535_gsp_msg_run_cpu_sequencer()
1558 nvkm_error(subdev, "unknown sequencer opcode %08x\n", cmd->opCode); in r535_gsp_msg_run_cpu_sequencer()
1559 return -EINVAL; in r535_gsp_msg_run_cpu_sequencer()
1569 struct nvkm_subdev *subdev = &gsp->subdev; in r535_gsp_booter_unload()
1570 struct nvkm_device *device = subdev->device; in r535_gsp_booter_unload()
1575 if (!wpr2_hi) { in r535_gsp_booter_unload()
1576 nvkm_debug(subdev, "WPR2 not set - skipping booter unload\n"); in r535_gsp_booter_unload()
1580 ret = nvkm_falcon_fw_boot(&gsp->booter.unload, &gsp->subdev, true, &mbox0, &mbox1, 0, 0); in r535_gsp_booter_unload()
1581 if (WARN_ON(ret)) in r535_gsp_booter_unload()
1585 if (WARN_ON(wpr2_hi)) in r535_gsp_booter_unload()
1586 return -EIO; in r535_gsp_booter_unload()
1596 ret = nvkm_falcon_fw_boot(&gsp->booter.load, &gsp->subdev, true, &mbox0, &mbox1, 0, 0); in r535_gsp_booter_load()
1597 if (ret) in r535_gsp_booter_load()
1600 nvkm_falcon_wr32(&gsp->falcon, 0x080, gsp->boot.app_version); in r535_gsp_booter_load()
1602 if (WARN_ON(!nvkm_falcon_riscv_active(&gsp->falcon))) in r535_gsp_booter_load()
1603 return -EIO; in r535_gsp_booter_load()
1614 ret = nvkm_gsp_mem_ctor(gsp, 0x1000, &gsp->wpr_meta); in r535_gsp_wpr_meta_init()
1615 if (ret) in r535_gsp_wpr_meta_init()
1618 meta = gsp->wpr_meta.data; in r535_gsp_wpr_meta_init()
1620 meta->magic = GSP_FW_WPR_META_MAGIC; in r535_gsp_wpr_meta_init()
1621 meta->revision = GSP_FW_WPR_META_REVISION; in r535_gsp_wpr_meta_init()
1623 meta->sysmemAddrOfRadix3Elf = gsp->radix3.mem[0].addr; in r535_gsp_wpr_meta_init()
1624 meta->sizeOfRadix3Elf = gsp->fb.wpr2.elf.size; in r535_gsp_wpr_meta_init()
1626 meta->sysmemAddrOfBootloader = gsp->boot.fw.addr; in r535_gsp_wpr_meta_init()
1627 meta->sizeOfBootloader = gsp->boot.fw.size; in r535_gsp_wpr_meta_init()
1628 meta->bootloaderCodeOffset = gsp->boot.code_offset; in r535_gsp_wpr_meta_init()
1629 meta->bootloaderDataOffset = gsp->boot.data_offset; in r535_gsp_wpr_meta_init()
1630 meta->bootloaderManifestOffset = gsp->boot.manifest_offset; in r535_gsp_wpr_meta_init()
1632 meta->sysmemAddrOfSignature = gsp->sig.addr; in r535_gsp_wpr_meta_init()
1633 meta->sizeOfSignature = gsp->sig.size; in r535_gsp_wpr_meta_init()
1635 meta->gspFwRsvdStart = gsp->fb.heap.addr; in r535_gsp_wpr_meta_init()
1636 meta->nonWprHeapOffset = gsp->fb.heap.addr; in r535_gsp_wpr_meta_init()
1637 meta->nonWprHeapSize = gsp->fb.heap.size; in r535_gsp_wpr_meta_init()
1638 meta->gspFwWprStart = gsp->fb.wpr2.addr; in r535_gsp_wpr_meta_init()
1639 meta->gspFwHeapOffset = gsp->fb.wpr2.heap.addr; in r535_gsp_wpr_meta_init()
1640 meta->gspFwHeapSize = gsp->fb.wpr2.heap.size; in r535_gsp_wpr_meta_init()
1641 meta->gspFwOffset = gsp->fb.wpr2.elf.addr; in r535_gsp_wpr_meta_init()
1642 meta->bootBinOffset = gsp->fb.wpr2.boot.addr; in r535_gsp_wpr_meta_init()
1643 meta->frtsOffset = gsp->fb.wpr2.frts.addr; in r535_gsp_wpr_meta_init()
1644 meta->frtsSize = gsp->fb.wpr2.frts.size; in r535_gsp_wpr_meta_init()
1645 meta->gspFwWprEnd = ALIGN_DOWN(gsp->fb.bios.vga_workspace.addr, 0x20000); in r535_gsp_wpr_meta_init()
1646 meta->fbSize = gsp->fb.size; in r535_gsp_wpr_meta_init()
1647 meta->vgaWorkspaceOffset = gsp->fb.bios.vga_workspace.addr; in r535_gsp_wpr_meta_init()
1648 meta->vgaWorkspaceSize = gsp->fb.bios.vga_workspace.size; in r535_gsp_wpr_meta_init()
1649 meta->bootCount = 0; in r535_gsp_wpr_meta_init()
1650 meta->partitionRpcAddr = 0; in r535_gsp_wpr_meta_init()
1651 meta->partitionRpcRequestOffset = 0; in r535_gsp_wpr_meta_init()
1652 meta->partitionRpcReplyOffset = 0; in r535_gsp_wpr_meta_init()
1653 meta->verified = 0; in r535_gsp_wpr_meta_init()
1666 gsp->shm.cmdq.size = 0x40000; in r535_gsp_shared_init()
1667 gsp->shm.msgq.size = 0x40000; in r535_gsp_shared_init()
1669 gsp->shm.ptes.nr = (gsp->shm.cmdq.size + gsp->shm.msgq.size) >> GSP_PAGE_SHIFT; in r535_gsp_shared_init()
1670 gsp->shm.ptes.nr += DIV_ROUND_UP(gsp->shm.ptes.nr * sizeof(u64), GSP_PAGE_SIZE); in r535_gsp_shared_init()
1671 gsp->shm.ptes.size = ALIGN(gsp->shm.ptes.nr * sizeof(u64), GSP_PAGE_SIZE); in r535_gsp_shared_init()
1673 ret = nvkm_gsp_mem_ctor(gsp, gsp->shm.ptes.size + in r535_gsp_shared_init()
1674 gsp->shm.cmdq.size + in r535_gsp_shared_init()
1675 gsp->shm.msgq.size, in r535_gsp_shared_init()
1676 &gsp->shm.mem); in r535_gsp_shared_init()
1677 if (ret) in r535_gsp_shared_init()
1680 gsp->shm.ptes.ptr = gsp->shm.mem.data; in r535_gsp_shared_init()
1681 gsp->shm.cmdq.ptr = (u8 *)gsp->shm.ptes.ptr + gsp->shm.ptes.size; in r535_gsp_shared_init()
1682 gsp->shm.msgq.ptr = (u8 *)gsp->shm.cmdq.ptr + gsp->shm.cmdq.size; in r535_gsp_shared_init()
1684 for (i = 0; i < gsp->shm.ptes.nr; i++) in r535_gsp_shared_init()
1685 gsp->shm.ptes.ptr[i] = gsp->shm.mem.addr + (i << GSP_PAGE_SHIFT); in r535_gsp_shared_init()
1687 cmdq = gsp->shm.cmdq.ptr; in r535_gsp_shared_init()
1688 cmdq->tx.version = 0; in r535_gsp_shared_init()
1689 cmdq->tx.size = gsp->shm.cmdq.size; in r535_gsp_shared_init()
1690 cmdq->tx.entryOff = GSP_PAGE_SIZE; in r535_gsp_shared_init()
1691 cmdq->tx.msgSize = GSP_PAGE_SIZE; in r535_gsp_shared_init()
1692 cmdq->tx.msgCount = (cmdq->tx.size - cmdq->tx.entryOff) / cmdq->tx.msgSize; in r535_gsp_shared_init()
1693 cmdq->tx.writePtr = 0; in r535_gsp_shared_init()
1694 cmdq->tx.flags = 1; in r535_gsp_shared_init()
1695 cmdq->tx.rxHdrOff = offsetof(typeof(*cmdq), rx.readPtr); in r535_gsp_shared_init()
1697 msgq = gsp->shm.msgq.ptr; in r535_gsp_shared_init()
1699 gsp->cmdq.cnt = cmdq->tx.msgCount; in r535_gsp_shared_init()
1700 gsp->cmdq.wptr = &cmdq->tx.writePtr; in r535_gsp_shared_init()
1701 gsp->cmdq.rptr = &msgq->rx.readPtr; in r535_gsp_shared_init()
1702 gsp->msgq.cnt = cmdq->tx.msgCount; in r535_gsp_shared_init()
1703 gsp->msgq.wptr = &msgq->tx.writePtr; in r535_gsp_shared_init()
1704 gsp->msgq.rptr = &cmdq->rx.readPtr; in r535_gsp_shared_init()
1714 if (!resume) { in r535_gsp_rmargs_init()
1716 if (ret) in r535_gsp_rmargs_init()
1719 ret = nvkm_gsp_mem_ctor(gsp, 0x1000, &gsp->rmargs); in r535_gsp_rmargs_init()
1720 if (ret) in r535_gsp_rmargs_init()
1724 args = gsp->rmargs.data; in r535_gsp_rmargs_init()
1725 args->messageQueueInitArguments.sharedMemPhysAddr = gsp->shm.mem.addr; in r535_gsp_rmargs_init()
1726 args->messageQueueInitArguments.pageTableEntryCount = gsp->shm.ptes.nr; in r535_gsp_rmargs_init()
1727 args->messageQueueInitArguments.cmdQueueOffset = in r535_gsp_rmargs_init()
1728 (u8 *)gsp->shm.cmdq.ptr - (u8 *)gsp->shm.mem.data; in r535_gsp_rmargs_init()
1729 args->messageQueueInitArguments.statQueueOffset = in r535_gsp_rmargs_init()
1730 (u8 *)gsp->shm.msgq.ptr - (u8 *)gsp->shm.mem.data; in r535_gsp_rmargs_init()
1732 if (!resume) { in r535_gsp_rmargs_init()
1733 args->srInitArguments.oldLevel = 0; in r535_gsp_rmargs_init()
1734 args->srInitArguments.flags = 0; in r535_gsp_rmargs_init()
1735 args->srInitArguments.bInPMTransition = 0; in r535_gsp_rmargs_init()
1737 args->srInitArguments.oldLevel = NV2080_CTRL_GPU_SET_POWER_STATE_GPU_LEVEL_3; in r535_gsp_rmargs_init()
1738 args->srInitArguments.flags = 0; in r535_gsp_rmargs_init()
1739 args->srInitArguments.bInPMTransition = 1; in r535_gsp_rmargs_init()
1757 * create_pte_array() - creates a PTE array of a physically contiguous buffer
1762 * GSP-RM sometimes expects physically-contiguous buffers to have an array of
1764 * the buffer to be physically discontiguous, GSP-RM does not currently
1783 * r535_gsp_libos_init() -- create the libos arguments structure
1785 * The logging buffers are byte queues that contain encoded printf-like
1786 * messages from GSP-RM. They need to be decoded by a special application
1789 * The 'loginit' buffer contains logs from early GSP-RM init and
1791 * written to directly by GSP-RM and can be any multiple of GSP_PAGE_SIZE.
1796 * The GSP only understands 4K pages (GSP_PAGE_SIZE), so even if the kernel is
1801 * The buffers must be a multiple of GSP_PAGE_SIZE. GSP-RM also currently
1806 * init_done RPC.
1817 ret = nvkm_gsp_mem_ctor(gsp, 0x1000, &gsp->libos); in r535_gsp_libos_init()
1818 if (ret) in r535_gsp_libos_init()
1821 args = gsp->libos.data; in r535_gsp_libos_init()
1823 ret = nvkm_gsp_mem_ctor(gsp, 0x10000, &gsp->loginit); in r535_gsp_libos_init()
1824 if (ret) in r535_gsp_libos_init()
1828 args[0].pa = gsp->loginit.addr; in r535_gsp_libos_init()
1829 args[0].size = gsp->loginit.size; in r535_gsp_libos_init()
1832 create_pte_array(gsp->loginit.data + sizeof(u64), gsp->loginit.addr, gsp->loginit.size); in r535_gsp_libos_init()
1834 ret = nvkm_gsp_mem_ctor(gsp, 0x10000, &gsp->logintr); in r535_gsp_libos_init()
1835 if (ret) in r535_gsp_libos_init()
1839 args[1].pa = gsp->logintr.addr; in r535_gsp_libos_init()
1840 args[1].size = gsp->logintr.size; in r535_gsp_libos_init()
1843 create_pte_array(gsp->logintr.data + sizeof(u64), gsp->logintr.addr, gsp->logintr.size); in r535_gsp_libos_init()
1845 ret = nvkm_gsp_mem_ctor(gsp, 0x10000, &gsp->logrm); in r535_gsp_libos_init()
1846 if (ret) in r535_gsp_libos_init()
1850 args[2].pa = gsp->logrm.addr; in r535_gsp_libos_init()
1851 args[2].size = gsp->logrm.size; in r535_gsp_libos_init()
1854 create_pte_array(gsp->logrm.data + sizeof(u64), gsp->logrm.addr, gsp->logrm.size); in r535_gsp_libos_init()
1857 if (ret) in r535_gsp_libos_init()
1861 args[3].pa = gsp->rmargs.addr; in r535_gsp_libos_init()
1862 args[3].size = gsp->rmargs.size; in r535_gsp_libos_init()
1874 dma_unmap_sgtable(device->dev, sgt, DMA_BIDIRECTIONAL, 0); in nvkm_gsp_sg_free()
1893 if (ret) in nvkm_gsp_sg()
1899 if (!page) { in nvkm_gsp_sg()
1901 return -ENOMEM; in nvkm_gsp_sg()
1907 ret = dma_map_sgtable(device->dev, sgt, DMA_BIDIRECTIONAL, 0); in nvkm_gsp_sg()
1908 if (ret) in nvkm_gsp_sg()
1917 for (int i = ARRAY_SIZE(rx3->mem) - 1; i >= 0; i--) in nvkm_gsp_radix3_dtor()
1918 nvkm_gsp_mem_dtor(gsp, &rx3->mem[i]); in nvkm_gsp_radix3_dtor()
1922 * nvkm_gsp_radix3_sg - build a radix3 table from a S/G list
1924 * The GSP uses a three-level page table, called radix3, to map the firmware.
1925 * Each 64-bit "pointer" in the table is either the bus address of an entry in
1943 * result is that GSP-RM must translate the bus addresses in the table to GSP
1956 for (int i = ARRAY_SIZE(rx3->mem) - 1; i >= 0; i--) { in nvkm_gsp_radix3_sg()
1962 ret = nvkm_gsp_mem_ctor(gsp, bufsize, &rx3->mem[i]); in nvkm_gsp_radix3_sg()
1963 if (ret) in nvkm_gsp_radix3_sg()
1966 ptes = rx3->mem[i].data; in nvkm_gsp_radix3_sg()
1967 if (i == 2) { in nvkm_gsp_radix3_sg()
1979 size = rx3->mem[i].size; in nvkm_gsp_radix3_sg()
1980 addr = rx3->mem[i].addr; in nvkm_gsp_radix3_sg()
1992 if (!gsp->running) in r535_gsp_fini()
1995 if (suspend) { in r535_gsp_fini()
1996 GspFwWprMeta *meta = gsp->wpr_meta.data; in r535_gsp_fini()
1997 u64 len = meta->gspFwWprEnd - meta->gspFwWprStart; in r535_gsp_fini()
2000 ret = nvkm_gsp_sg(gsp->subdev.device, len, &gsp->sr.sgt); in r535_gsp_fini()
2001 if (ret) in r535_gsp_fini()
2004 ret = nvkm_gsp_radix3_sg(gsp, &gsp->sr.sgt, len, &gsp->sr.radix3); in r535_gsp_fini()
2005 if (ret) in r535_gsp_fini()
2008 ret = nvkm_gsp_mem_ctor(gsp, sizeof(*sr), &gsp->sr.meta); in r535_gsp_fini()
2009 if (ret) in r535_gsp_fini()
2012 sr = gsp->sr.meta.data; in r535_gsp_fini()
2013 sr->magic = GSP_FW_SR_META_MAGIC; in r535_gsp_fini()
2014 sr->revision = GSP_FW_SR_META_REVISION; in r535_gsp_fini()
2015 sr->sysmemAddrOfSuspendResumeData = gsp->sr.radix3.mem[0].addr; in r535_gsp_fini()
2016 sr->sizeOfSuspendResumeData = len; in r535_gsp_fini()
2018 mbox0 = lower_32_bits(gsp->sr.meta.addr); in r535_gsp_fini()
2019 mbox1 = upper_32_bits(gsp->sr.meta.addr); in r535_gsp_fini()
2023 if (WARN_ON(ret)) in r535_gsp_fini()
2026 nvkm_msec(gsp->subdev.device, 2000, in r535_gsp_fini()
2027 if (nvkm_falcon_rd32(&gsp->falcon, 0x040) & 0x80000000) in r535_gsp_fini()
2031 nvkm_falcon_reset(&gsp->falcon); in r535_gsp_fini()
2039 gsp->running = false; in r535_gsp_fini()
2049 if (!gsp->sr.meta.data) { in r535_gsp_init()
2050 mbox0 = lower_32_bits(gsp->wpr_meta.addr); in r535_gsp_init()
2051 mbox1 = upper_32_bits(gsp->wpr_meta.addr); in r535_gsp_init()
2055 mbox0 = lower_32_bits(gsp->sr.meta.addr); in r535_gsp_init()
2056 mbox1 = upper_32_bits(gsp->sr.meta.addr); in r535_gsp_init()
2059 /* Execute booter to handle (eventually...) booting GSP-RM. */ in r535_gsp_init()
2061 if (WARN_ON(ret)) in r535_gsp_init()
2065 if (ret) in r535_gsp_init()
2068 gsp->running = true; in r535_gsp_init()
2071 if (gsp->sr.meta.data) { in r535_gsp_init()
2072 nvkm_gsp_mem_dtor(gsp, &gsp->sr.meta); in r535_gsp_init()
2073 nvkm_gsp_radix3_dtor(gsp, &gsp->sr.radix3); in r535_gsp_init()
2074 nvkm_gsp_sg_free(gsp->subdev.device, &gsp->sr.sgt); in r535_gsp_init()
2078 if (ret == 0) in r535_gsp_init()
2087 const struct firmware *fw = gsp->fws.bl; in r535_gsp_rm_boot_ctor()
2092 hdr = nvfw_bin_hdr(&gsp->subdev, fw->data); in r535_gsp_rm_boot_ctor()
2093 desc = (void *)fw->data + hdr->header_offset; in r535_gsp_rm_boot_ctor()
2095 ret = nvkm_gsp_mem_ctor(gsp, hdr->data_size, &gsp->boot.fw); in r535_gsp_rm_boot_ctor()
2096 if (ret) in r535_gsp_rm_boot_ctor()
2099 memcpy(gsp->boot.fw.data, fw->data + hdr->data_offset, hdr->data_size); in r535_gsp_rm_boot_ctor()
2101 gsp->boot.code_offset = desc->monitorCodeOffset; in r535_gsp_rm_boot_ctor()
2102 gsp->boot.data_offset = desc->monitorDataOffset; in r535_gsp_rm_boot_ctor()
2103 gsp->boot.manifest_offset = desc->manifestOffset; in r535_gsp_rm_boot_ctor()
2104 gsp->boot.app_version = desc->appVersion; in r535_gsp_rm_boot_ctor()
2116 const u8 *img = gsp->fws.rm->data; in r535_gsp_elf_section()
2118 const struct elf64_shdr *shdr = (const struct elf64_shdr *)&img[ehdr->e_shoff]; in r535_gsp_elf_section()
2119 const char *names = &img[shdr[ehdr->e_shstrndx].sh_offset]; in r535_gsp_elf_section()
2121 for (int i = 0; i < ehdr->e_shnum; i++, shdr++) { in r535_gsp_elf_section()
2122 if (!strcmp(&names[shdr->sh_name], name)) { in r535_gsp_elf_section()
2123 *pdata = &img[shdr->sh_offset]; in r535_gsp_elf_section()
2124 *psize = shdr->sh_size; in r535_gsp_elf_section()
2129 nvkm_error(&gsp->subdev, "section '%s' not found\n", name); in r535_gsp_elf_section()
2130 return -ENOENT; in r535_gsp_elf_section()
2136 nvkm_firmware_put(gsp->fws.bl); in r535_gsp_dtor_fws()
2137 gsp->fws.bl = NULL; in r535_gsp_dtor_fws()
2138 nvkm_firmware_put(gsp->fws.booter.unload); in r535_gsp_dtor_fws()
2139 gsp->fws.booter.unload = NULL; in r535_gsp_dtor_fws()
2140 nvkm_firmware_put(gsp->fws.booter.load); in r535_gsp_dtor_fws()
2141 gsp->fws.booter.load = NULL; in r535_gsp_dtor_fws()
2142 nvkm_firmware_put(gsp->fws.rm); in r535_gsp_dtor_fws()
2143 gsp->fws.rm = NULL; in r535_gsp_dtor_fws()
2149 idr_destroy(&gsp->client_id.idr); in r535_gsp_dtor()
2150 mutex_destroy(&gsp->client_id.mutex); in r535_gsp_dtor()
2152 nvkm_gsp_radix3_dtor(gsp, &gsp->radix3); in r535_gsp_dtor()
2153 nvkm_gsp_mem_dtor(gsp, &gsp->sig); in r535_gsp_dtor()
2154 nvkm_firmware_dtor(&gsp->fw); in r535_gsp_dtor()
2156 nvkm_falcon_fw_dtor(&gsp->booter.unload); in r535_gsp_dtor()
2157 nvkm_falcon_fw_dtor(&gsp->booter.load); in r535_gsp_dtor()
2159 mutex_destroy(&gsp->msgq.mutex); in r535_gsp_dtor()
2160 mutex_destroy(&gsp->cmdq.mutex); in r535_gsp_dtor()
2164 nvkm_gsp_mem_dtor(gsp, &gsp->rmargs); in r535_gsp_dtor()
2165 nvkm_gsp_mem_dtor(gsp, &gsp->wpr_meta); in r535_gsp_dtor()
2166 nvkm_gsp_mem_dtor(gsp, &gsp->shm.mem); in r535_gsp_dtor()
2167 nvkm_gsp_mem_dtor(gsp, &gsp->loginit); in r535_gsp_dtor()
2168 nvkm_gsp_mem_dtor(gsp, &gsp->logintr); in r535_gsp_dtor()
2169 nvkm_gsp_mem_dtor(gsp, &gsp->logrm); in r535_gsp_dtor()
2175 struct nvkm_device *device = gsp->subdev.device; in r535_gsp_oneinit()
2180 mutex_init(&gsp->cmdq.mutex); in r535_gsp_oneinit()
2181 mutex_init(&gsp->msgq.mutex); in r535_gsp_oneinit()
2183 ret = gsp->func->booter.ctor(gsp, "booter-load", gsp->fws.booter.load, in r535_gsp_oneinit()
2184 &device->sec2->falcon, &gsp->booter.load); in r535_gsp_oneinit()
2185 if (ret) in r535_gsp_oneinit()
2188 ret = gsp->func->booter.ctor(gsp, "booter-unload", gsp->fws.booter.unload, in r535_gsp_oneinit()
2189 &device->sec2->falcon, &gsp->booter.unload); in r535_gsp_oneinit()
2190 if (ret) in r535_gsp_oneinit()
2193 /* Load GSP firmware from ELF image into DMA-accessible memory. */ in r535_gsp_oneinit()
2195 if (ret) in r535_gsp_oneinit()
2198 ret = nvkm_firmware_ctor(&r535_gsp_fw, "gsp-rm", device, data, size, &gsp->fw); in r535_gsp_oneinit()
2199 if (ret) in r535_gsp_oneinit()
2203 ret = r535_gsp_elf_section(gsp, gsp->func->sig_section, &data, &size); in r535_gsp_oneinit()
2204 if (ret) in r535_gsp_oneinit()
2207 ret = nvkm_gsp_mem_ctor(gsp, ALIGN(size, 256), &gsp->sig); in r535_gsp_oneinit()
2208 if (ret) in r535_gsp_oneinit()
2211 memcpy(gsp->sig.data, data, size); in r535_gsp_oneinit()
2214 ret = nvkm_gsp_radix3_sg(gsp, &gsp->fw.mem.sgt, gsp->fw.len, &gsp->radix3); in r535_gsp_oneinit()
2215 if (ret) in r535_gsp_oneinit()
2230 if (ret) in r535_gsp_oneinit()
2233 /* Release FW images - we've copied them to DMA buffers now. */ in r535_gsp_oneinit()
2237 gsp->fb.wpr2.frts.size = 0x100000; in r535_gsp_oneinit()
2238 gsp->fb.wpr2.frts.addr = ALIGN_DOWN(gsp->fb.bios.addr, 0x20000) - gsp->fb.wpr2.frts.size; in r535_gsp_oneinit()
2240 gsp->fb.wpr2.boot.size = gsp->boot.fw.size; in r535_gsp_oneinit()
2241 gsp->fb.wpr2.boot.addr = ALIGN_DOWN(gsp->fb.wpr2.frts.addr - gsp->fb.wpr2.boot.size, 0x1000); in r535_gsp_oneinit()
2243 gsp->fb.wpr2.elf.size = gsp->fw.len; in r535_gsp_oneinit()
2244 gsp->fb.wpr2.elf.addr = ALIGN_DOWN(gsp->fb.wpr2.boot.addr - gsp->fb.wpr2.elf.size, 0x10000); in r535_gsp_oneinit()
2247 u32 fb_size_gb = DIV_ROUND_UP_ULL(gsp->fb.size, 1 << 30); in r535_gsp_oneinit()
2249 gsp->fb.wpr2.heap.size = in r535_gsp_oneinit()
2250 gsp->func->wpr_heap.os_carveout_size + in r535_gsp_oneinit()
2251 gsp->func->wpr_heap.base_size + in r535_gsp_oneinit()
2255 gsp->fb.wpr2.heap.size = max(gsp->fb.wpr2.heap.size, gsp->func->wpr_heap.min_size); in r535_gsp_oneinit()
2258 gsp->fb.wpr2.heap.addr = ALIGN_DOWN(gsp->fb.wpr2.elf.addr - gsp->fb.wpr2.heap.size, 0x100000); in r535_gsp_oneinit()
2259 gsp->fb.wpr2.heap.size = ALIGN_DOWN(gsp->fb.wpr2.elf.addr - gsp->fb.wpr2.heap.addr, 0x100000); in r535_gsp_oneinit()
2261 gsp->fb.wpr2.addr = ALIGN_DOWN(gsp->fb.wpr2.heap.addr - sizeof(GspFwWprMeta), 0x100000); in r535_gsp_oneinit()
2262 gsp->fb.wpr2.size = gsp->fb.wpr2.frts.addr + gsp->fb.wpr2.frts.size - gsp->fb.wpr2.addr; in r535_gsp_oneinit()
2264 gsp->fb.heap.size = 0x100000; in r535_gsp_oneinit()
2265 gsp->fb.heap.addr = gsp->fb.wpr2.addr - gsp->fb.heap.size; in r535_gsp_oneinit()
2268 if (WARN_ON(ret)) in r535_gsp_oneinit()
2272 if (WARN_ON(ret)) in r535_gsp_oneinit()
2276 if (WARN_ON(ret)) in r535_gsp_oneinit()
2280 if (WARN_ON(ret)) in r535_gsp_oneinit()
2284 if (WARN_ON(ret)) in r535_gsp_oneinit()
2287 /* Reset GSP into RISC-V mode. */ in r535_gsp_oneinit()
2288 ret = gsp->func->reset(gsp); in r535_gsp_oneinit()
2289 if (WARN_ON(ret)) in r535_gsp_oneinit()
2292 nvkm_falcon_wr32(&gsp->falcon, 0x040, lower_32_bits(gsp->libos.addr)); in r535_gsp_oneinit()
2293 nvkm_falcon_wr32(&gsp->falcon, 0x044, upper_32_bits(gsp->libos.addr)); in r535_gsp_oneinit()
2295 mutex_init(&gsp->client_id.mutex); in r535_gsp_oneinit()
2296 idr_init(&gsp->client_id.idr); in r535_gsp_oneinit()
2306 snprintf(fwname, sizeof(fwname), "gsp/%s-%s", name, ver); in r535_gsp_load_fw()
2307 return nvkm_firmware_get(&gsp->subdev, fwname, 0, pfw); in r535_gsp_load_fw()
2313 struct nvkm_subdev *subdev = &gsp->subdev; in r535_gsp_load()
2315 bool enable_gsp = fwif->enable; in r535_gsp_load()
2317 #if IS_ENABLED(CONFIG_DRM_NOUVEAU_GSP_DEFAULT) in r535_gsp_load()
2320 if (!nvkm_boolopt(subdev->device->cfgopt, "NvGspRm", enable_gsp)) in r535_gsp_load()
2321 return -EINVAL; in r535_gsp_load()
2323 if ((ret = r535_gsp_load_fw(gsp, "gsp", fwif->ver, &gsp->fws.rm)) || in r535_gsp_load()
2324 (ret = r535_gsp_load_fw(gsp, "booter_load", fwif->ver, &gsp->fws.booter.load)) || in r535_gsp_load()
2325 (ret = r535_gsp_load_fw(gsp, "booter_unload", fwif->ver, &gsp->fws.booter.unload)) || in r535_gsp_load()
2326 (ret = r535_gsp_load_fw(gsp, "bootloader", fwif->ver, &gsp->fws.bl))) { in r535_gsp_load()
2335 MODULE_FIRMWARE("nvidia/"#chip"/gsp/booter_load-535.113.01.bin"); \
2336 MODULE_FIRMWARE("nvidia/"#chip"/gsp/booter_unload-535.113.01.bin"); \
2337 MODULE_FIRMWARE("nvidia/"#chip"/gsp/bootloader-535.113.01.bin"); \
2338 MODULE_FIRMWARE("nvidia/"#chip"/gsp/gsp-535.113.01.bin")