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 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 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 * 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 * 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