Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

drm/nouveau/nvkm: factor out current GSP RPC command policies

There can be multiple cases of handling the GSP RPC messages, which are
the reply of GSP RPC commands according to the requirement of the
callers and the nature of the GSP RPC commands.

The current supported reply policies are "callers don't care" and "receive
the entire message" according to the requirement of the callers. To
introduce a new policy, factor out the current RPC command reply polices.
Also, centralize the handling of the reply in a single function.

Factor out NVKM_GSP_RPC_REPLY_NOWAIT as "callers don't care" and
NVKM_GSP_RPC_REPLY_RECV as "receive the entire message". Introduce a
kernel doc to document the policies. Factor out
r535_gsp_rpc_handle_reply().

No functional change is intended for small GSP RPC commands. For large GSP
commands, the caller decides the policy of how to handle the returned GSP
RPC message.

Cc: Ben Skeggs <bskeggs@nvidia.com>
Cc: Alexandre Courbot <acourbot@nvidia.com>
Signed-off-by: Zhi Wang <zhiw@nvidia.com>
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20250227013554.8269-2-zhiw@nvidia.com

authored by

Zhi Wang and committed by
Danilo Krummrich
4570355f 2c7aafc0

+72 -44
+3
Documentation/gpu/nouveau.rst
··· 27 27 28 28 .. kernel-doc:: drivers/gpu/drm/nouveau/nvkm/subdev/gsp/r535.c 29 29 :doc: GSP message queue element 30 + 31 + .. kernel-doc:: drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h 32 + :doc: GSP message handling policy
+28 -6
drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h
··· 31 31 struct nvkm_gsp_event; 32 32 typedef void (*nvkm_gsp_event_func)(struct nvkm_gsp_event *, void *repv, u32 repc); 33 33 34 + /** 35 + * DOC: GSP message handling policy 36 + * 37 + * When sending a GSP RPC command, there can be multiple cases of handling 38 + * the GSP RPC messages, which are the reply of GSP RPC commands, according 39 + * to the requirement of the callers and the nature of the GSP RPC commands. 40 + * 41 + * NVKM_GSP_RPC_REPLY_NOWAIT - If specified, immediately return to the 42 + * caller after the GSP RPC command is issued. 43 + * 44 + * NVKM_GSP_RPC_REPLY_RECV - If specified, wait and receive the entire GSP 45 + * RPC message after the GSP RPC command is issued. 46 + * 47 + */ 48 + enum nvkm_gsp_rpc_reply_policy { 49 + NVKM_GSP_RPC_REPLY_NOWAIT = 0, 50 + NVKM_GSP_RPC_REPLY_RECV, 51 + }; 52 + 34 53 struct nvkm_gsp { 35 54 const struct nvkm_gsp_func *func; 36 55 struct nvkm_subdev subdev; ··· 207 188 208 189 const struct nvkm_gsp_rm { 209 190 void *(*rpc_get)(struct nvkm_gsp *, u32 fn, u32 argc); 210 - void *(*rpc_push)(struct nvkm_gsp *, void *argv, bool wait, u32 repc); 191 + void *(*rpc_push)(struct nvkm_gsp *gsp, void *argv, 192 + enum nvkm_gsp_rpc_reply_policy policy, u32 repc); 211 193 void (*rpc_done)(struct nvkm_gsp *gsp, void *repv); 212 194 213 195 void *(*rm_ctrl_get)(struct nvkm_gsp_object *, u32 cmd, u32 argc); ··· 275 255 } 276 256 277 257 static inline void * 278 - nvkm_gsp_rpc_push(struct nvkm_gsp *gsp, void *argv, bool wait, u32 repc) 258 + nvkm_gsp_rpc_push(struct nvkm_gsp *gsp, void *argv, 259 + enum nvkm_gsp_rpc_reply_policy policy, u32 repc) 279 260 { 280 - return gsp->rm->rpc_push(gsp, argv, wait, repc); 261 + return gsp->rm->rpc_push(gsp, argv, policy, repc); 281 262 } 282 263 283 264 static inline void * ··· 289 268 if (IS_ERR_OR_NULL(argv)) 290 269 return argv; 291 270 292 - return nvkm_gsp_rpc_push(gsp, argv, true, argc); 271 + return nvkm_gsp_rpc_push(gsp, argv, NVKM_GSP_RPC_REPLY_RECV, argc); 293 272 } 294 273 295 274 static inline int 296 - nvkm_gsp_rpc_wr(struct nvkm_gsp *gsp, void *argv, bool wait) 275 + nvkm_gsp_rpc_wr(struct nvkm_gsp *gsp, void *argv, 276 + enum nvkm_gsp_rpc_reply_policy policy) 297 277 { 298 - void *repv = nvkm_gsp_rpc_push(gsp, argv, wait, 0); 278 + void *repv = nvkm_gsp_rpc_push(gsp, argv, policy, 0); 299 279 300 280 if (IS_ERR(repv)) 301 281 return PTR_ERR(repv);
+1 -1
drivers/gpu/drm/nouveau/nvkm/subdev/bar/r535.c
··· 56 56 rpc->info.entryValue = addr ? ((addr >> 4) | 2) : 0; /* PD3 entry format! */ 57 57 rpc->info.entryLevelShift = 47; //XXX: probably fetch this from mmu! 58 58 59 - return nvkm_gsp_rpc_wr(gsp, rpc, true); 59 + return nvkm_gsp_rpc_wr(gsp, rpc, NVKM_GSP_RPC_REPLY_RECV); 60 60 } 61 61 62 62 static void
+39 -36
drivers/gpu/drm/nouveau/nvkm/subdev/gsp/r535.c
··· 585 585 } 586 586 587 587 static void * 588 - r535_gsp_rpc_send(struct nvkm_gsp *gsp, void *payload, bool wait, 589 - u32 gsp_rpc_len) 588 + r535_gsp_rpc_handle_reply(struct nvkm_gsp *gsp, u32 fn, 589 + enum nvkm_gsp_rpc_reply_policy policy, 590 + u32 gsp_rpc_len) 591 + { 592 + struct nvfw_gsp_rpc *reply; 593 + void *repv = NULL; 594 + 595 + switch (policy) { 596 + case NVKM_GSP_RPC_REPLY_NOWAIT: 597 + break; 598 + case NVKM_GSP_RPC_REPLY_RECV: 599 + reply = r535_gsp_msg_recv(gsp, fn, gsp_rpc_len); 600 + if (!IS_ERR_OR_NULL(reply)) 601 + repv = reply->data; 602 + else 603 + repv = reply; 604 + break; 605 + } 606 + 607 + return repv; 608 + } 609 + 610 + static void * 611 + r535_gsp_rpc_send(struct nvkm_gsp *gsp, void *payload, 612 + enum nvkm_gsp_rpc_reply_policy policy, u32 gsp_rpc_len) 590 613 { 591 614 struct nvfw_gsp_rpc *rpc = to_gsp_hdr(payload, rpc); 592 - struct nvfw_gsp_rpc *msg; 593 615 u32 fn = rpc->function; 594 - void *repv = NULL; 595 616 int ret; 596 617 597 618 if (gsp->subdev.debug >= NV_DBG_TRACE) { ··· 626 605 if (ret) 627 606 return ERR_PTR(ret); 628 607 629 - if (wait) { 630 - msg = r535_gsp_msg_recv(gsp, fn, gsp_rpc_len); 631 - if (!IS_ERR_OR_NULL(msg)) 632 - repv = msg->data; 633 - else 634 - repv = msg; 635 - } 636 - 637 - return repv; 608 + return r535_gsp_rpc_handle_reply(gsp, fn, policy, gsp_rpc_len); 638 609 } 639 610 640 611 static void ··· 810 797 rpc->params.hRoot = client->object.handle; 811 798 rpc->params.hObjectParent = 0; 812 799 rpc->params.hObjectOld = object->handle; 813 - return nvkm_gsp_rpc_wr(gsp, rpc, true); 800 + return nvkm_gsp_rpc_wr(gsp, rpc, NVKM_GSP_RPC_REPLY_RECV); 814 801 } 815 802 816 803 static void ··· 828 815 struct nvkm_gsp *gsp = object->client->gsp; 829 816 void *ret = NULL; 830 817 831 - rpc = nvkm_gsp_rpc_push(gsp, rpc, true, sizeof(*rpc)); 818 + rpc = nvkm_gsp_rpc_push(gsp, rpc, NVKM_GSP_RPC_REPLY_RECV, sizeof(*rpc)); 832 819 if (IS_ERR_OR_NULL(rpc)) 833 820 return rpc; 834 821 ··· 889 876 struct nvkm_gsp *gsp = object->client->gsp; 890 877 int ret = 0; 891 878 892 - rpc = nvkm_gsp_rpc_push(gsp, rpc, true, repc); 879 + rpc = nvkm_gsp_rpc_push(gsp, rpc, NVKM_GSP_RPC_REPLY_RECV, repc); 893 880 if (IS_ERR_OR_NULL(rpc)) { 894 881 *params = NULL; 895 882 return PTR_ERR(rpc); ··· 961 948 } 962 949 963 950 static void * 964 - r535_gsp_rpc_push(struct nvkm_gsp *gsp, void *payload, bool wait, 965 - u32 gsp_rpc_len) 951 + r535_gsp_rpc_push(struct nvkm_gsp *gsp, void *payload, 952 + enum nvkm_gsp_rpc_reply_policy policy, u32 gsp_rpc_len) 966 953 { 967 954 struct nvfw_gsp_rpc *rpc = to_gsp_hdr(payload, rpc); 968 955 struct r535_gsp_msg *msg = to_gsp_hdr(rpc, msg); ··· 980 967 rpc->length = sizeof(*rpc) + max_payload_size; 981 968 msg->checksum = rpc->length; 982 969 983 - repv = r535_gsp_rpc_send(gsp, payload, false, 0); 970 + repv = r535_gsp_rpc_send(gsp, payload, NVKM_GSP_RPC_REPLY_NOWAIT, 0); 984 971 if (IS_ERR(repv)) 985 972 goto done; 986 973 ··· 1001 988 1002 989 memcpy(next, payload, size); 1003 990 1004 - repv = r535_gsp_rpc_send(gsp, next, false, 0); 991 + repv = r535_gsp_rpc_send(gsp, next, NVKM_GSP_RPC_REPLY_NOWAIT, 0); 1005 992 if (IS_ERR(repv)) 1006 993 goto done; 1007 994 ··· 1010 997 } 1011 998 1012 999 /* Wait for reply. */ 1013 - rpc = r535_gsp_msg_recv(gsp, fn, payload_size + 1014 - sizeof(*rpc)); 1015 - if (!IS_ERR_OR_NULL(rpc)) { 1016 - if (wait) { 1017 - repv = rpc->data; 1018 - } else { 1019 - nvkm_gsp_rpc_done(gsp, rpc); 1020 - repv = NULL; 1021 - } 1022 - } else { 1023 - repv = wait ? rpc : NULL; 1024 - } 1000 + repv = r535_gsp_rpc_handle_reply(gsp, fn, policy, payload_size + 1001 + sizeof(*rpc)); 1025 1002 } else { 1026 - repv = r535_gsp_rpc_send(gsp, payload, wait, gsp_rpc_len); 1003 + repv = r535_gsp_rpc_send(gsp, payload, policy, gsp_rpc_len); 1027 1004 } 1028 1005 1029 1006 done: ··· 1330 1327 rpc->newLevel = NV2080_CTRL_GPU_SET_POWER_STATE_GPU_LEVEL_0; 1331 1328 } 1332 1329 1333 - return nvkm_gsp_rpc_wr(gsp, rpc, true); 1330 + return nvkm_gsp_rpc_wr(gsp, rpc, NVKM_GSP_RPC_REPLY_RECV); 1334 1331 } 1335 1332 1336 1333 enum registry_type { ··· 1687 1684 1688 1685 build_registry(gsp, rpc); 1689 1686 1690 - return nvkm_gsp_rpc_wr(gsp, rpc, false); 1687 + return nvkm_gsp_rpc_wr(gsp, rpc, NVKM_GSP_RPC_REPLY_NOWAIT); 1691 1688 1692 1689 fail: 1693 1690 clean_registry(gsp); ··· 1896 1893 info->pciConfigMirrorSize = 0x001000; 1897 1894 r535_gsp_acpi_info(gsp, &info->acpiMethodData); 1898 1895 1899 - return nvkm_gsp_rpc_wr(gsp, info, false); 1896 + return nvkm_gsp_rpc_wr(gsp, info, NVKM_GSP_RPC_REPLY_NOWAIT); 1900 1897 } 1901 1898 1902 1899 static int
+1 -1
drivers/gpu/drm/nouveau/nvkm/subdev/instmem/r535.c
··· 105 105 rpc->pteDesc.pte_pde[i].pte = (phys >> 12) + i; 106 106 } 107 107 108 - ret = nvkm_gsp_rpc_wr(gsp, rpc, true); 108 + ret = nvkm_gsp_rpc_wr(gsp, rpc, NVKM_GSP_RPC_REPLY_RECV); 109 109 if (ret) 110 110 return ret; 111 111