Merge branch 'next' into for-linus
[sfrench/cifs-2.6.git] / drivers / accel / ivpu / ivpu_jsm_msg.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (C) 2020-2023 Intel Corporation
4  */
5
6 #include "ivpu_drv.h"
7 #include "ivpu_ipc.h"
8 #include "ivpu_jsm_msg.h"
9
10 int ivpu_jsm_register_db(struct ivpu_device *vdev, u32 ctx_id, u32 db_id,
11                          u64 jobq_base, u32 jobq_size)
12 {
13         struct vpu_jsm_msg req = { .type = VPU_JSM_MSG_REGISTER_DB };
14         struct vpu_jsm_msg resp;
15         int ret = 0;
16
17         req.payload.register_db.db_idx = db_id;
18         req.payload.register_db.jobq_base = jobq_base;
19         req.payload.register_db.jobq_size = jobq_size;
20         req.payload.register_db.host_ssid = ctx_id;
21
22         ret = ivpu_ipc_send_receive(vdev, &req, VPU_JSM_MSG_REGISTER_DB_DONE, &resp,
23                                     VPU_IPC_CHAN_ASYNC_CMD, vdev->timeout.jsm);
24         if (ret) {
25                 ivpu_err(vdev, "Failed to register doorbell %d: %d\n", db_id, ret);
26                 return ret;
27         }
28
29         ivpu_dbg(vdev, JSM, "Doorbell %d registered to context %d\n", db_id, ctx_id);
30
31         return 0;
32 }
33
34 int ivpu_jsm_unregister_db(struct ivpu_device *vdev, u32 db_id)
35 {
36         struct vpu_jsm_msg req = { .type = VPU_JSM_MSG_UNREGISTER_DB };
37         struct vpu_jsm_msg resp;
38         int ret = 0;
39
40         req.payload.unregister_db.db_idx = db_id;
41
42         ret = ivpu_ipc_send_receive(vdev, &req, VPU_JSM_MSG_UNREGISTER_DB_DONE, &resp,
43                                     VPU_IPC_CHAN_ASYNC_CMD, vdev->timeout.jsm);
44         if (ret) {
45                 ivpu_warn(vdev, "Failed to unregister doorbell %d: %d\n", db_id, ret);
46                 return ret;
47         }
48
49         ivpu_dbg(vdev, JSM, "Doorbell %d unregistered\n", db_id);
50
51         return 0;
52 }
53
54 int ivpu_jsm_get_heartbeat(struct ivpu_device *vdev, u32 engine, u64 *heartbeat)
55 {
56         struct vpu_jsm_msg req = { .type = VPU_JSM_MSG_QUERY_ENGINE_HB };
57         struct vpu_jsm_msg resp;
58         int ret;
59
60         if (engine > VPU_ENGINE_COPY)
61                 return -EINVAL;
62
63         req.payload.query_engine_hb.engine_idx = engine;
64
65         ret = ivpu_ipc_send_receive(vdev, &req, VPU_JSM_MSG_QUERY_ENGINE_HB_DONE, &resp,
66                                     VPU_IPC_CHAN_ASYNC_CMD, vdev->timeout.jsm);
67         if (ret) {
68                 ivpu_err(vdev, "Failed to get heartbeat from engine %d: %d\n", engine, ret);
69                 return ret;
70         }
71
72         *heartbeat = resp.payload.query_engine_hb_done.heartbeat;
73         return ret;
74 }
75
76 int ivpu_jsm_reset_engine(struct ivpu_device *vdev, u32 engine)
77 {
78         struct vpu_jsm_msg req = { .type = VPU_JSM_MSG_ENGINE_RESET };
79         struct vpu_jsm_msg resp;
80         int ret;
81
82         if (engine > VPU_ENGINE_COPY)
83                 return -EINVAL;
84
85         req.payload.engine_reset.engine_idx = engine;
86
87         ret = ivpu_ipc_send_receive(vdev, &req, VPU_JSM_MSG_ENGINE_RESET_DONE, &resp,
88                                     VPU_IPC_CHAN_ASYNC_CMD, vdev->timeout.jsm);
89         if (ret)
90                 ivpu_err(vdev, "Failed to reset engine %d: %d\n", engine, ret);
91
92         return ret;
93 }
94
95 int ivpu_jsm_preempt_engine(struct ivpu_device *vdev, u32 engine, u32 preempt_id)
96 {
97         struct vpu_jsm_msg req = { .type = VPU_JSM_MSG_ENGINE_PREEMPT };
98         struct vpu_jsm_msg resp;
99         int ret;
100
101         if (engine > VPU_ENGINE_COPY)
102                 return -EINVAL;
103
104         req.payload.engine_preempt.engine_idx = engine;
105         req.payload.engine_preempt.preempt_id = preempt_id;
106
107         ret = ivpu_ipc_send_receive(vdev, &req, VPU_JSM_MSG_ENGINE_PREEMPT_DONE, &resp,
108                                     VPU_IPC_CHAN_ASYNC_CMD, vdev->timeout.jsm);
109         if (ret)
110                 ivpu_err(vdev, "Failed to preempt engine %d: %d\n", engine, ret);
111
112         return ret;
113 }
114
115 int ivpu_jsm_dyndbg_control(struct ivpu_device *vdev, char *command, size_t size)
116 {
117         struct vpu_jsm_msg req = { .type = VPU_JSM_MSG_DYNDBG_CONTROL };
118         struct vpu_jsm_msg resp;
119         int ret;
120
121         if (!strncpy(req.payload.dyndbg_control.dyndbg_cmd, command, VPU_DYNDBG_CMD_MAX_LEN - 1))
122                 return -ENOMEM;
123
124         ret = ivpu_ipc_send_receive(vdev, &req, VPU_JSM_MSG_DYNDBG_CONTROL_RSP, &resp,
125                                     VPU_IPC_CHAN_ASYNC_CMD, vdev->timeout.jsm);
126         if (ret)
127                 ivpu_warn(vdev, "Failed to send command \"%s\": ret %d\n", command, ret);
128
129         return ret;
130 }
131
132 int ivpu_jsm_trace_get_capability(struct ivpu_device *vdev, u32 *trace_destination_mask,
133                                   u64 *trace_hw_component_mask)
134 {
135         struct vpu_jsm_msg req = { .type = VPU_JSM_MSG_TRACE_GET_CAPABILITY };
136         struct vpu_jsm_msg resp;
137         int ret;
138
139         ret = ivpu_ipc_send_receive(vdev, &req, VPU_JSM_MSG_TRACE_GET_CAPABILITY_RSP, &resp,
140                                     VPU_IPC_CHAN_ASYNC_CMD, vdev->timeout.jsm);
141         if (ret) {
142                 ivpu_warn(vdev, "Failed to get trace capability: %d\n", ret);
143                 return ret;
144         }
145
146         *trace_destination_mask = resp.payload.trace_capability.trace_destination_mask;
147         *trace_hw_component_mask = resp.payload.trace_capability.trace_hw_component_mask;
148
149         return ret;
150 }
151
152 int ivpu_jsm_trace_set_config(struct ivpu_device *vdev, u32 trace_level, u32 trace_destination_mask,
153                               u64 trace_hw_component_mask)
154 {
155         struct vpu_jsm_msg req = { .type = VPU_JSM_MSG_TRACE_SET_CONFIG };
156         struct vpu_jsm_msg resp;
157         int ret;
158
159         req.payload.trace_config.trace_level = trace_level;
160         req.payload.trace_config.trace_destination_mask = trace_destination_mask;
161         req.payload.trace_config.trace_hw_component_mask = trace_hw_component_mask;
162
163         ret = ivpu_ipc_send_receive(vdev, &req, VPU_JSM_MSG_TRACE_SET_CONFIG_RSP, &resp,
164                                     VPU_IPC_CHAN_ASYNC_CMD, vdev->timeout.jsm);
165         if (ret)
166                 ivpu_warn(vdev, "Failed to set config: %d\n", ret);
167
168         return ret;
169 }
170
171 int ivpu_jsm_context_release(struct ivpu_device *vdev, u32 host_ssid)
172 {
173         struct vpu_jsm_msg req = { .type = VPU_JSM_MSG_SSID_RELEASE };
174         struct vpu_jsm_msg resp;
175
176         req.payload.ssid_release.host_ssid = host_ssid;
177
178         return ivpu_ipc_send_receive(vdev, &req, VPU_JSM_MSG_SSID_RELEASE_DONE, &resp,
179                                      VPU_IPC_CHAN_ASYNC_CMD, vdev->timeout.jsm);
180 }