1 /*
2 * Copyright 2023 Red Hat Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 */
22 #include <rm/rpc.h>
23
24 #include "nvrm/alloc.h"
25 #include "nvrm/rpcfn.h"
26
27 static int
r535_gsp_rpc_rm_free(struct nvkm_gsp_object * object)28 r535_gsp_rpc_rm_free(struct nvkm_gsp_object *object)
29 {
30 struct nvkm_gsp_client *client = object->client;
31 struct nvkm_gsp *gsp = client->gsp;
32 rpc_free_v03_00 *rpc;
33
34 nvkm_debug(&gsp->subdev, "cli:0x%08x obj:0x%08x free\n",
35 client->object.handle, object->handle);
36
37 rpc = nvkm_gsp_rpc_get(gsp, NV_VGPU_MSG_FUNCTION_FREE, sizeof(*rpc));
38 if (WARN_ON(IS_ERR_OR_NULL(rpc)))
39 return -EIO;
40
41 rpc->params.hRoot = client->object.handle;
42 rpc->params.hObjectParent = 0;
43 rpc->params.hObjectOld = object->handle;
44 return nvkm_gsp_rpc_wr(gsp, rpc, NVKM_GSP_RPC_REPLY_RECV);
45 }
46
47 static void
r535_gsp_rpc_rm_alloc_done(struct nvkm_gsp_object * object,void * params)48 r535_gsp_rpc_rm_alloc_done(struct nvkm_gsp_object *object, void *params)
49 {
50 rpc_gsp_rm_alloc_v03_00 *rpc = to_payload_hdr(params, rpc);
51
52 nvkm_gsp_rpc_done(object->client->gsp, rpc);
53 }
54
55 static void *
r535_gsp_rpc_rm_alloc_push(struct nvkm_gsp_object * object,void * params)56 r535_gsp_rpc_rm_alloc_push(struct nvkm_gsp_object *object, void *params)
57 {
58 rpc_gsp_rm_alloc_v03_00 *rpc = to_payload_hdr(params, rpc);
59 struct nvkm_gsp *gsp = object->client->gsp;
60 void *ret = NULL;
61
62 rpc = nvkm_gsp_rpc_push(gsp, rpc, NVKM_GSP_RPC_REPLY_RECV, sizeof(*rpc));
63 if (IS_ERR_OR_NULL(rpc))
64 return rpc;
65
66 if (rpc->status) {
67 ret = ERR_PTR(r535_rpc_status_to_errno(rpc->status));
68 if (PTR_ERR(ret) != -EAGAIN && PTR_ERR(ret) != -EBUSY)
69 nvkm_error(&gsp->subdev, "RM_ALLOC: 0x%x\n", rpc->status);
70 }
71
72 nvkm_gsp_rpc_done(gsp, rpc);
73
74 return ret;
75 }
76
77 static void *
r535_gsp_rpc_rm_alloc_get(struct nvkm_gsp_object * object,u32 oclass,u32 params_size)78 r535_gsp_rpc_rm_alloc_get(struct nvkm_gsp_object *object, u32 oclass,
79 u32 params_size)
80 {
81 struct nvkm_gsp_client *client = object->client;
82 struct nvkm_gsp *gsp = client->gsp;
83 rpc_gsp_rm_alloc_v03_00 *rpc;
84
85 nvkm_debug(&gsp->subdev, "cli:0x%08x obj:0x%08x new obj:0x%08x\n",
86 client->object.handle, object->parent->handle,
87 object->handle);
88
89 nvkm_debug(&gsp->subdev, "cls:0x%08x params_size:%d\n", oclass,
90 params_size);
91
92 rpc = nvkm_gsp_rpc_get(gsp, NV_VGPU_MSG_FUNCTION_GSP_RM_ALLOC,
93 sizeof(*rpc) + params_size);
94 if (IS_ERR(rpc))
95 return rpc;
96
97 rpc->hClient = client->object.handle;
98 rpc->hParent = object->parent->handle;
99 rpc->hObject = object->handle;
100 rpc->hClass = oclass;
101 rpc->status = 0;
102 rpc->paramsSize = params_size;
103 return rpc->params;
104 }
105
106 const struct nvkm_rm_api_alloc
107 r535_alloc = {
108 .get = r535_gsp_rpc_rm_alloc_get,
109 .push = r535_gsp_rpc_rm_alloc_push,
110 .done = r535_gsp_rpc_rm_alloc_done,
111 .free = r535_gsp_rpc_rm_free,
112 };
113