xref: /linux/drivers/accel/amdxdna/aie2_message.c (revision 32e940f2bd3b16551f23ea44be47f6f5d1746d64)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (C) 2023-2024, Advanced Micro Devices, Inc.
4  */
5 
6 #include <drm/amdxdna_accel.h>
7 #include <drm/drm_cache.h>
8 #include <drm/drm_device.h>
9 #include <drm/drm_gem.h>
10 #include <drm/drm_gem_shmem_helper.h>
11 #include <drm/drm_print.h>
12 #include <drm/gpu_scheduler.h>
13 #include <linux/bitfield.h>
14 #include <linux/errno.h>
15 #include <linux/pci.h>
16 #include <linux/types.h>
17 #include <linux/xarray.h>
18 
19 #include "aie2_msg_priv.h"
20 #include "aie2_pci.h"
21 #include "amdxdna_ctx.h"
22 #include "amdxdna_gem.h"
23 #include "amdxdna_mailbox.h"
24 #include "amdxdna_mailbox_helper.h"
25 #include "amdxdna_pci_drv.h"
26 
27 #define DECLARE_AIE2_MSG(name, op) \
28 	DECLARE_XDNA_MSG_COMMON(name, op, MAX_AIE2_STATUS_CODE)
29 
30 #define EXEC_MSG_OPS(xdna)	((xdna)->dev_handle->exec_msg_ops)
31 
aie2_send_mgmt_msg_wait(struct amdxdna_dev_hdl * ndev,struct xdna_mailbox_msg * msg)32 static int aie2_send_mgmt_msg_wait(struct amdxdna_dev_hdl *ndev,
33 				   struct xdna_mailbox_msg *msg)
34 {
35 	struct amdxdna_dev *xdna = ndev->xdna;
36 	struct xdna_notify *hdl = msg->handle;
37 	int ret;
38 
39 	if (!ndev->mgmt_chann)
40 		return -ENODEV;
41 
42 	ret = xdna_send_msg_wait(xdna, ndev->mgmt_chann, msg);
43 	if (ret == -ETIME)
44 		aie2_destroy_mgmt_chann(ndev);
45 
46 	if (!ret && *hdl->status != AIE2_STATUS_SUCCESS) {
47 		XDNA_ERR(xdna, "command opcode 0x%x failed, status 0x%x",
48 			 msg->opcode, *hdl->data);
49 		ret = -EINVAL;
50 	}
51 
52 	return ret;
53 }
54 
aie2_alloc_msg_buffer(struct amdxdna_dev_hdl * ndev,u32 * size,dma_addr_t * dma_addr)55 void *aie2_alloc_msg_buffer(struct amdxdna_dev_hdl *ndev, u32 *size,
56 			    dma_addr_t *dma_addr)
57 {
58 	struct amdxdna_dev *xdna = ndev->xdna;
59 	void *vaddr;
60 	int order;
61 
62 	*size = max(*size, SZ_8K);
63 	order = get_order(*size);
64 	if (order > MAX_PAGE_ORDER)
65 		return ERR_PTR(-EINVAL);
66 	*size = PAGE_SIZE << order;
67 
68 	if (amdxdna_iova_on(xdna))
69 		return amdxdna_iommu_alloc(xdna, *size, dma_addr);
70 
71 	vaddr = dma_alloc_noncoherent(xdna->ddev.dev, *size, dma_addr,
72 				      DMA_FROM_DEVICE, GFP_KERNEL);
73 	if (!vaddr)
74 		return ERR_PTR(-ENOMEM);
75 
76 	return vaddr;
77 }
78 
aie2_free_msg_buffer(struct amdxdna_dev_hdl * ndev,size_t size,void * cpu_addr,dma_addr_t dma_addr)79 void aie2_free_msg_buffer(struct amdxdna_dev_hdl *ndev, size_t size,
80 			  void *cpu_addr, dma_addr_t dma_addr)
81 {
82 	struct amdxdna_dev *xdna = ndev->xdna;
83 
84 	if (amdxdna_iova_on(xdna)) {
85 		amdxdna_iommu_free(xdna, size, cpu_addr, dma_addr);
86 		return;
87 	}
88 
89 	dma_free_noncoherent(xdna->ddev.dev, size, cpu_addr, dma_addr, DMA_FROM_DEVICE);
90 }
91 
aie2_suspend_fw(struct amdxdna_dev_hdl * ndev)92 int aie2_suspend_fw(struct amdxdna_dev_hdl *ndev)
93 {
94 	DECLARE_AIE2_MSG(suspend, MSG_OP_SUSPEND);
95 	int ret;
96 
97 	ret = aie2_send_mgmt_msg_wait(ndev, &msg);
98 	if (ret) {
99 		XDNA_ERR(ndev->xdna, "Failed to suspend fw, ret %d", ret);
100 		return ret;
101 	}
102 
103 	return aie2_psp_waitmode_poll(ndev->psp_hdl);
104 }
105 
aie2_resume_fw(struct amdxdna_dev_hdl * ndev)106 int aie2_resume_fw(struct amdxdna_dev_hdl *ndev)
107 {
108 	DECLARE_AIE2_MSG(suspend, MSG_OP_RESUME);
109 
110 	return aie2_send_mgmt_msg_wait(ndev, &msg);
111 }
112 
aie2_set_runtime_cfg(struct amdxdna_dev_hdl * ndev,u32 type,u64 value)113 int aie2_set_runtime_cfg(struct amdxdna_dev_hdl *ndev, u32 type, u64 value)
114 {
115 	DECLARE_AIE2_MSG(set_runtime_cfg, MSG_OP_SET_RUNTIME_CONFIG);
116 	int ret;
117 
118 	req.type = type;
119 	req.value = value;
120 
121 	ret = aie2_send_mgmt_msg_wait(ndev, &msg);
122 	if (ret) {
123 		XDNA_ERR(ndev->xdna, "Failed to set runtime config, ret %d", ret);
124 		return ret;
125 	}
126 
127 	return 0;
128 }
129 
aie2_get_runtime_cfg(struct amdxdna_dev_hdl * ndev,u32 type,u64 * value)130 int aie2_get_runtime_cfg(struct amdxdna_dev_hdl *ndev, u32 type, u64 *value)
131 {
132 	DECLARE_AIE2_MSG(get_runtime_cfg, MSG_OP_GET_RUNTIME_CONFIG);
133 	int ret;
134 
135 	req.type = type;
136 	ret = aie2_send_mgmt_msg_wait(ndev, &msg);
137 	if (ret) {
138 		XDNA_ERR(ndev->xdna, "Failed to get runtime config, ret %d", ret);
139 		return ret;
140 	}
141 
142 	*value = resp.value;
143 	return 0;
144 }
145 
aie2_assign_mgmt_pasid(struct amdxdna_dev_hdl * ndev,u16 pasid)146 int aie2_assign_mgmt_pasid(struct amdxdna_dev_hdl *ndev, u16 pasid)
147 {
148 	DECLARE_AIE2_MSG(assign_mgmt_pasid, MSG_OP_ASSIGN_MGMT_PASID);
149 
150 	req.pasid = pasid;
151 
152 	return aie2_send_mgmt_msg_wait(ndev, &msg);
153 }
154 
aie2_query_aie_version(struct amdxdna_dev_hdl * ndev,struct aie_version * version)155 int aie2_query_aie_version(struct amdxdna_dev_hdl *ndev, struct aie_version *version)
156 {
157 	DECLARE_AIE2_MSG(aie_version_info, MSG_OP_QUERY_AIE_VERSION);
158 	struct amdxdna_dev *xdna = ndev->xdna;
159 	int ret;
160 
161 	ret = aie2_send_mgmt_msg_wait(ndev, &msg);
162 	if (ret)
163 		return ret;
164 
165 	XDNA_DBG(xdna, "Query AIE version - major: %u minor: %u completed",
166 		 resp.major, resp.minor);
167 
168 	version->major = resp.major;
169 	version->minor = resp.minor;
170 
171 	return 0;
172 }
173 
aie2_query_aie_metadata(struct amdxdna_dev_hdl * ndev,struct aie_metadata * metadata)174 int aie2_query_aie_metadata(struct amdxdna_dev_hdl *ndev, struct aie_metadata *metadata)
175 {
176 	DECLARE_AIE2_MSG(aie_tile_info, MSG_OP_QUERY_AIE_TILE_INFO);
177 	int ret;
178 
179 	ret = aie2_send_mgmt_msg_wait(ndev, &msg);
180 	if (ret)
181 		return ret;
182 
183 	metadata->size = resp.info.size;
184 	metadata->cols = resp.info.cols;
185 	metadata->rows = resp.info.rows;
186 
187 	metadata->version.major = resp.info.major;
188 	metadata->version.minor = resp.info.minor;
189 
190 	metadata->core.row_count = resp.info.core_rows;
191 	metadata->core.row_start = resp.info.core_row_start;
192 	metadata->core.dma_channel_count = resp.info.core_dma_channels;
193 	metadata->core.lock_count = resp.info.core_locks;
194 	metadata->core.event_reg_count = resp.info.core_events;
195 
196 	metadata->mem.row_count = resp.info.mem_rows;
197 	metadata->mem.row_start = resp.info.mem_row_start;
198 	metadata->mem.dma_channel_count = resp.info.mem_dma_channels;
199 	metadata->mem.lock_count = resp.info.mem_locks;
200 	metadata->mem.event_reg_count = resp.info.mem_events;
201 
202 	metadata->shim.row_count = resp.info.shim_rows;
203 	metadata->shim.row_start = resp.info.shim_row_start;
204 	metadata->shim.dma_channel_count = resp.info.shim_dma_channels;
205 	metadata->shim.lock_count = resp.info.shim_locks;
206 	metadata->shim.event_reg_count = resp.info.shim_events;
207 
208 	return 0;
209 }
210 
aie2_query_firmware_version(struct amdxdna_dev_hdl * ndev,struct amdxdna_fw_ver * fw_ver)211 int aie2_query_firmware_version(struct amdxdna_dev_hdl *ndev,
212 				struct amdxdna_fw_ver *fw_ver)
213 {
214 	DECLARE_AIE2_MSG(firmware_version, MSG_OP_GET_FIRMWARE_VERSION);
215 	int ret;
216 
217 	ret = aie2_send_mgmt_msg_wait(ndev, &msg);
218 	if (ret)
219 		return ret;
220 
221 	fw_ver->major = resp.major;
222 	fw_ver->minor = resp.minor;
223 	fw_ver->sub = resp.sub;
224 	fw_ver->build = resp.build;
225 
226 	return 0;
227 }
228 
aie2_destroy_context_req(struct amdxdna_dev_hdl * ndev,u32 id)229 static int aie2_destroy_context_req(struct amdxdna_dev_hdl *ndev, u32 id)
230 {
231 	DECLARE_AIE2_MSG(destroy_ctx, MSG_OP_DESTROY_CONTEXT);
232 	struct amdxdna_dev *xdna = ndev->xdna;
233 	int ret;
234 
235 	req.context_id = id;
236 	ret = aie2_send_mgmt_msg_wait(ndev, &msg);
237 	if (ret && ret != -ENODEV)
238 		XDNA_WARN(xdna, "Destroy context failed, ret %d", ret);
239 	else if (ret == -ENODEV)
240 		XDNA_DBG(xdna, "Destroy context: device already stopped");
241 
242 	return ret;
243 }
244 
aie2_get_context_priority(struct amdxdna_dev_hdl * ndev,struct amdxdna_hwctx * hwctx)245 static u32 aie2_get_context_priority(struct amdxdna_dev_hdl *ndev,
246 				     struct amdxdna_hwctx *hwctx)
247 {
248 	if (!AIE2_FEATURE_ON(ndev, AIE2_PREEMPT))
249 		return PRIORITY_HIGH;
250 
251 	switch (hwctx->qos.priority) {
252 	case AMDXDNA_QOS_REALTIME_PRIORITY:
253 		return PRIORITY_REALTIME;
254 	case AMDXDNA_QOS_HIGH_PRIORITY:
255 		return PRIORITY_HIGH;
256 	case AMDXDNA_QOS_NORMAL_PRIORITY:
257 		return PRIORITY_NORMAL;
258 	case AMDXDNA_QOS_LOW_PRIORITY:
259 		return PRIORITY_LOW;
260 	default:
261 		return PRIORITY_HIGH;
262 	}
263 }
264 
aie2_create_context(struct amdxdna_dev_hdl * ndev,struct amdxdna_hwctx * hwctx)265 int aie2_create_context(struct amdxdna_dev_hdl *ndev, struct amdxdna_hwctx *hwctx)
266 {
267 	DECLARE_AIE2_MSG(create_ctx, MSG_OP_CREATE_CONTEXT);
268 	struct amdxdna_dev *xdna = ndev->xdna;
269 	struct xdna_mailbox_chann_res x2i;
270 	struct xdna_mailbox_chann_res i2x;
271 	struct cq_pair *cq_pair;
272 	u32 intr_reg;
273 	int ret;
274 
275 	req.aie_type = 1;
276 	req.start_col = hwctx->start_col;
277 	req.num_col = hwctx->num_col;
278 	req.num_unused_col = hwctx->num_unused_col;
279 	req.num_cq_pairs_requested = 1;
280 	req.pasid = amdxdna_pasid_on(hwctx->client) ? hwctx->client->pasid : 0;
281 	req.context_priority = aie2_get_context_priority(ndev, hwctx);
282 
283 	ret = aie2_send_mgmt_msg_wait(ndev, &msg);
284 	if (ret)
285 		return ret;
286 
287 	hwctx->fw_ctx_id = resp.context_id;
288 	if (WARN_ON_ONCE(hwctx->fw_ctx_id == -1))
289 		return -EINVAL;
290 
291 	if (ndev->force_preempt_enabled) {
292 		ret = aie2_runtime_cfg(ndev, AIE2_RT_CFG_FORCE_PREEMPT, &hwctx->fw_ctx_id);
293 		if (ret) {
294 			XDNA_ERR(xdna, "failed to enable force preempt %d", ret);
295 			goto del_ctx_req;
296 		}
297 	}
298 
299 	cq_pair = &resp.cq_pair[0];
300 	x2i.mb_head_ptr_reg = AIE2_MBOX_OFF(ndev, cq_pair->x2i_q.head_addr);
301 	x2i.mb_tail_ptr_reg = AIE2_MBOX_OFF(ndev, cq_pair->x2i_q.tail_addr);
302 	x2i.rb_start_addr   = AIE2_SRAM_OFF(ndev, cq_pair->x2i_q.buf_addr);
303 	x2i.rb_size	    = cq_pair->x2i_q.buf_size;
304 
305 	i2x.mb_head_ptr_reg = AIE2_MBOX_OFF(ndev, cq_pair->i2x_q.head_addr);
306 	i2x.mb_tail_ptr_reg = AIE2_MBOX_OFF(ndev, cq_pair->i2x_q.tail_addr);
307 	i2x.rb_start_addr   = AIE2_SRAM_OFF(ndev, cq_pair->i2x_q.buf_addr);
308 	i2x.rb_size	    = cq_pair->i2x_q.buf_size;
309 
310 	ret = pci_irq_vector(to_pci_dev(xdna->ddev.dev), resp.msix_id);
311 	if (ret == -EINVAL) {
312 		XDNA_ERR(xdna, "Alloc IRQ failed %d", ret);
313 		goto del_ctx_req;
314 	}
315 
316 	intr_reg = i2x.mb_head_ptr_reg + 4;
317 	hwctx->priv->mbox_chann = xdna_mailbox_alloc_channel(ndev->mbox);
318 	if (!hwctx->priv->mbox_chann) {
319 		XDNA_ERR(xdna, "Not able to create channel");
320 		ret = -EINVAL;
321 		goto del_ctx_req;
322 	}
323 
324 	ret = xdna_mailbox_start_channel(hwctx->priv->mbox_chann, &x2i, &i2x,
325 					 intr_reg, ret);
326 	if (ret) {
327 		XDNA_ERR(xdna, "Not able to create channel");
328 		ret = -EINVAL;
329 		goto free_channel;
330 	}
331 	ndev->hwctx_num++;
332 
333 	XDNA_DBG(xdna, "Mailbox channel irq: %d, msix_id: %d", ret, resp.msix_id);
334 	XDNA_DBG(xdna, "Created fw ctx %d pasid %d", hwctx->fw_ctx_id, hwctx->client->pasid);
335 
336 	return 0;
337 
338 free_channel:
339 	xdna_mailbox_free_channel(hwctx->priv->mbox_chann);
340 del_ctx_req:
341 	aie2_destroy_context_req(ndev, hwctx->fw_ctx_id);
342 	return ret;
343 }
344 
aie2_destroy_context(struct amdxdna_dev_hdl * ndev,struct amdxdna_hwctx * hwctx)345 int aie2_destroy_context(struct amdxdna_dev_hdl *ndev, struct amdxdna_hwctx *hwctx)
346 {
347 	struct amdxdna_dev *xdna = ndev->xdna;
348 	int ret;
349 
350 	if (!hwctx->priv->mbox_chann)
351 		return 0;
352 
353 	xdna_mailbox_stop_channel(hwctx->priv->mbox_chann);
354 	ret = aie2_destroy_context_req(ndev, hwctx->fw_ctx_id);
355 	xdna_mailbox_free_channel(hwctx->priv->mbox_chann);
356 	XDNA_DBG(xdna, "Destroyed fw ctx %d", hwctx->fw_ctx_id);
357 	hwctx->priv->mbox_chann = NULL;
358 	hwctx->fw_ctx_id = -1;
359 	ndev->hwctx_num--;
360 
361 	return ret;
362 }
363 
aie2_map_host_buf(struct amdxdna_dev_hdl * ndev,u32 context_id,u64 addr,u64 size)364 int aie2_map_host_buf(struct amdxdna_dev_hdl *ndev, u32 context_id, u64 addr, u64 size)
365 {
366 	DECLARE_AIE2_MSG(map_host_buffer, MSG_OP_MAP_HOST_BUFFER);
367 	struct amdxdna_dev *xdna = ndev->xdna;
368 	int ret;
369 
370 	req.context_id = context_id;
371 	req.buf_addr = addr;
372 	req.buf_size = size;
373 	ret = aie2_send_mgmt_msg_wait(ndev, &msg);
374 	if (ret)
375 		return ret;
376 
377 	XDNA_DBG(xdna, "fw ctx %d map host buf addr 0x%llx size 0x%llx",
378 		 context_id, addr, size);
379 
380 	return 0;
381 }
382 
amdxdna_hwctx_col_map(struct amdxdna_hwctx * hwctx,void * arg)383 static int amdxdna_hwctx_col_map(struct amdxdna_hwctx *hwctx, void *arg)
384 {
385 	u32 *bitmap = arg;
386 
387 	*bitmap |= GENMASK(hwctx->start_col + hwctx->num_col - 1, hwctx->start_col);
388 
389 	return 0;
390 }
391 
aie2_query_status(struct amdxdna_dev_hdl * ndev,char __user * buf,u32 size,u32 * cols_filled)392 int aie2_query_status(struct amdxdna_dev_hdl *ndev, char __user *buf,
393 		      u32 size, u32 *cols_filled)
394 {
395 	DECLARE_AIE2_MSG(aie_column_info, MSG_OP_QUERY_COL_STATUS);
396 	struct amdxdna_dev *xdna = ndev->xdna;
397 	u32 buf_sz = size, aie_bitmap = 0;
398 	struct amdxdna_client *client;
399 	dma_addr_t dma_addr;
400 	u8 *buff_addr;
401 	int ret;
402 
403 	buff_addr = aie2_alloc_msg_buffer(ndev, &buf_sz, &dma_addr);
404 	if (IS_ERR(buff_addr))
405 		return PTR_ERR(buff_addr);
406 
407 	/* Go through each hardware context and mark the AIE columns that are active */
408 	list_for_each_entry(client, &xdna->client_list, node)
409 		amdxdna_hwctx_walk(client, &aie_bitmap, amdxdna_hwctx_col_map);
410 
411 	*cols_filled = 0;
412 	req.dump_buff_addr = dma_addr;
413 	req.dump_buff_size = buf_sz;
414 	req.num_cols = hweight32(aie_bitmap);
415 	req.aie_bitmap = aie_bitmap;
416 
417 	drm_clflush_virt_range(buff_addr, size); /* device can access */
418 	ret = aie2_send_mgmt_msg_wait(ndev, &msg);
419 	if (ret) {
420 		XDNA_ERR(xdna, "Error during NPU query, status %d", ret);
421 		goto fail;
422 	}
423 
424 	XDNA_DBG(xdna, "Query NPU status completed");
425 
426 	if (size < resp.size) {
427 		ret = -EINVAL;
428 		XDNA_ERR(xdna, "Bad buffer size. Available: %u. Needs: %u", size, resp.size);
429 		goto fail;
430 	}
431 
432 	if (copy_to_user(buf, buff_addr, resp.size)) {
433 		ret = -EFAULT;
434 		XDNA_ERR(xdna, "Failed to copy NPU status to user space");
435 		goto fail;
436 	}
437 
438 	*cols_filled = aie_bitmap;
439 
440 fail:
441 	aie2_free_msg_buffer(ndev, buf_sz, buff_addr, dma_addr);
442 	return ret;
443 }
444 
aie2_query_telemetry(struct amdxdna_dev_hdl * ndev,char __user * buf,u32 size,struct amdxdna_drm_query_telemetry_header * header)445 int aie2_query_telemetry(struct amdxdna_dev_hdl *ndev,
446 			 char __user *buf, u32 size,
447 			 struct amdxdna_drm_query_telemetry_header *header)
448 {
449 	DECLARE_AIE2_MSG(get_telemetry, MSG_OP_GET_TELEMETRY);
450 	struct amdxdna_dev *xdna = ndev->xdna;
451 	dma_addr_t dma_addr;
452 	u32 buf_sz = size;
453 	u8 *addr;
454 	int ret;
455 
456 	if (header->type >= MAX_TELEMETRY_TYPE)
457 		return -EINVAL;
458 
459 	addr = aie2_alloc_msg_buffer(ndev, &buf_sz, &dma_addr);
460 	if (IS_ERR(addr))
461 		return PTR_ERR(addr);
462 
463 	req.buf_addr = dma_addr;
464 	req.buf_size = buf_sz;
465 	req.type = header->type;
466 
467 	drm_clflush_virt_range(addr, size); /* device can access */
468 	ret = aie2_send_mgmt_msg_wait(ndev, &msg);
469 	if (ret) {
470 		XDNA_ERR(xdna, "Query telemetry failed, status %d", ret);
471 		goto free_buf;
472 	}
473 
474 	if (size < resp.size) {
475 		ret = -EINVAL;
476 		XDNA_ERR(xdna, "Bad buffer size. Available: %u. Needs: %u", size, resp.size);
477 		goto free_buf;
478 	}
479 
480 	if (copy_to_user(buf, addr, resp.size)) {
481 		ret = -EFAULT;
482 		XDNA_ERR(xdna, "Failed to copy telemetry to user space");
483 		goto free_buf;
484 	}
485 
486 	header->major = resp.major;
487 	header->minor = resp.minor;
488 
489 free_buf:
490 	aie2_free_msg_buffer(ndev, buf_sz, addr, dma_addr);
491 	return ret;
492 }
493 
aie2_register_asyn_event_msg(struct amdxdna_dev_hdl * ndev,dma_addr_t addr,u32 size,void * handle,int (* cb)(void *,void __iomem *,size_t))494 int aie2_register_asyn_event_msg(struct amdxdna_dev_hdl *ndev, dma_addr_t addr, u32 size,
495 				 void *handle, int (*cb)(void*, void __iomem *, size_t))
496 {
497 	struct async_event_msg_req req = { 0 };
498 	struct xdna_mailbox_msg msg = {
499 		.send_data = (u8 *)&req,
500 		.send_size = sizeof(req),
501 		.handle = handle,
502 		.opcode = MSG_OP_REGISTER_ASYNC_EVENT_MSG,
503 		.notify_cb = cb,
504 	};
505 
506 	req.buf_addr = addr;
507 	req.buf_size = size;
508 
509 	XDNA_DBG(ndev->xdna, "Register addr 0x%llx size 0x%x", addr, size);
510 	return xdna_mailbox_send_msg(ndev->mgmt_chann, &msg, TX_TIMEOUT);
511 }
512 
aie2_config_cu(struct amdxdna_hwctx * hwctx,int (* notify_cb)(void *,void __iomem *,size_t))513 int aie2_config_cu(struct amdxdna_hwctx *hwctx,
514 		   int (*notify_cb)(void *, void __iomem *, size_t))
515 {
516 	struct mailbox_channel *chann = hwctx->priv->mbox_chann;
517 	struct amdxdna_dev *xdna = hwctx->client->xdna;
518 	u32 shift = xdna->dev_info->dev_mem_buf_shift;
519 	struct config_cu_req req = { 0 };
520 	struct xdna_mailbox_msg msg;
521 	struct drm_gem_object *gobj;
522 	struct amdxdna_gem_obj *abo;
523 	int i;
524 
525 	if (!chann)
526 		return -ENODEV;
527 
528 	if (!hwctx->cus)
529 		return 0;
530 
531 	if (hwctx->cus->num_cus > MAX_NUM_CUS) {
532 		XDNA_DBG(xdna, "Exceed maximum CU %d", MAX_NUM_CUS);
533 		return -EINVAL;
534 	}
535 
536 	for (i = 0; i < hwctx->cus->num_cus; i++) {
537 		struct amdxdna_cu_config *cu = &hwctx->cus->cu_configs[i];
538 
539 		if (XDNA_MBZ_DBG(xdna, cu->pad, sizeof(cu->pad)))
540 			return -EINVAL;
541 
542 		gobj = drm_gem_object_lookup(hwctx->client->filp, cu->cu_bo);
543 		if (!gobj) {
544 			XDNA_ERR(xdna, "Lookup GEM object failed");
545 			return -EINVAL;
546 		}
547 		abo = to_xdna_obj(gobj);
548 
549 		if (abo->type != AMDXDNA_BO_DEV) {
550 			drm_gem_object_put(gobj);
551 			XDNA_ERR(xdna, "Invalid BO type");
552 			return -EINVAL;
553 		}
554 
555 		req.cfgs[i] = FIELD_PREP(AIE2_MSG_CFG_CU_PDI_ADDR,
556 					 amdxdna_gem_dev_addr(abo) >> shift);
557 		req.cfgs[i] |= FIELD_PREP(AIE2_MSG_CFG_CU_FUNC, cu->cu_func);
558 		XDNA_DBG(xdna, "CU %d full addr 0x%llx, cfg 0x%x", i,
559 			 amdxdna_gem_dev_addr(abo), req.cfgs[i]);
560 		drm_gem_object_put(gobj);
561 	}
562 	req.num_cus = hwctx->cus->num_cus;
563 
564 	msg.send_data = (u8 *)&req;
565 	msg.send_size = sizeof(req);
566 	msg.handle = hwctx;
567 	msg.opcode = MSG_OP_CONFIG_CU;
568 	msg.notify_cb = notify_cb;
569 	return xdna_mailbox_send_msg(chann, &msg, TX_TIMEOUT);
570 }
571 
aie2_init_exec_cu_req(struct amdxdna_gem_obj * cmd_bo,void * req,size_t * size,u32 * msg_op)572 static int aie2_init_exec_cu_req(struct amdxdna_gem_obj *cmd_bo, void *req,
573 				 size_t *size, u32 *msg_op)
574 {
575 	struct execute_buffer_req *cu_req = req;
576 	u32 cmd_len;
577 	void *cmd;
578 
579 	cmd = amdxdna_cmd_get_payload(cmd_bo, &cmd_len);
580 	if (cmd_len > sizeof(cu_req->payload))
581 		return -EINVAL;
582 
583 	cu_req->cu_idx = amdxdna_cmd_get_cu_idx(cmd_bo);
584 	if (cu_req->cu_idx == INVALID_CU_IDX)
585 		return -EINVAL;
586 
587 	memcpy(cu_req->payload, cmd, cmd_len);
588 
589 	*size = sizeof(*cu_req);
590 	*msg_op = MSG_OP_EXECUTE_BUFFER_CF;
591 	return 0;
592 }
593 
aie2_init_exec_dpu_req(struct amdxdna_gem_obj * cmd_bo,void * req,size_t * size,u32 * msg_op)594 static int aie2_init_exec_dpu_req(struct amdxdna_gem_obj *cmd_bo, void *req,
595 				  size_t *size, u32 *msg_op)
596 {
597 	struct exec_dpu_req *dpu_req = req;
598 	struct amdxdna_cmd_start_npu *sn;
599 	u32 cmd_len;
600 
601 	sn = amdxdna_cmd_get_payload(cmd_bo, &cmd_len);
602 	if (cmd_len - sizeof(*sn) > sizeof(dpu_req->payload))
603 		return -EINVAL;
604 
605 	dpu_req->cu_idx = amdxdna_cmd_get_cu_idx(cmd_bo);
606 	if (dpu_req->cu_idx == INVALID_CU_IDX)
607 		return -EINVAL;
608 
609 	dpu_req->inst_buf_addr = sn->buffer;
610 	dpu_req->inst_size = sn->buffer_size;
611 	dpu_req->inst_prop_cnt = sn->prop_count;
612 	memcpy(dpu_req->payload, sn->prop_args, cmd_len - sizeof(*sn));
613 
614 	*size = sizeof(*dpu_req);
615 	*msg_op = MSG_OP_EXEC_DPU;
616 	return 0;
617 }
618 
aie2_init_exec_chain_req(void * req,u64 slot_addr,size_t size,u32 cmd_cnt)619 static void aie2_init_exec_chain_req(void *req, u64 slot_addr, size_t size, u32 cmd_cnt)
620 {
621 	struct cmd_chain_req *chain_req = req;
622 
623 	chain_req->buf_addr = slot_addr;
624 	chain_req->buf_size = size;
625 	chain_req->count = cmd_cnt;
626 }
627 
aie2_init_npu_chain_req(void * req,u64 slot_addr,size_t size,u32 cmd_cnt)628 static void aie2_init_npu_chain_req(void *req, u64 slot_addr, size_t size, u32 cmd_cnt)
629 {
630 	struct cmd_chain_npu_req *npu_chain_req = req;
631 
632 	npu_chain_req->flags = 0;
633 	npu_chain_req->reserved = 0;
634 	npu_chain_req->buf_addr = slot_addr;
635 	npu_chain_req->buf_size = size;
636 	npu_chain_req->count = cmd_cnt;
637 }
638 
639 static int
aie2_cmdlist_fill_cf(struct amdxdna_gem_obj * cmd_bo,void * slot,size_t * size)640 aie2_cmdlist_fill_cf(struct amdxdna_gem_obj *cmd_bo, void *slot, size_t *size)
641 {
642 	struct cmd_chain_slot_execbuf_cf *cf_slot = slot;
643 	u32 cmd_len;
644 	void *cmd;
645 
646 	cmd = amdxdna_cmd_get_payload(cmd_bo, &cmd_len);
647 	if (*size < sizeof(*cf_slot) + cmd_len)
648 		return -EINVAL;
649 
650 	cf_slot->cu_idx = amdxdna_cmd_get_cu_idx(cmd_bo);
651 	if (cf_slot->cu_idx == INVALID_CU_IDX)
652 		return -EINVAL;
653 
654 	cf_slot->arg_cnt = cmd_len / sizeof(u32);
655 	memcpy(cf_slot->args, cmd, cmd_len);
656 	/* Accurate slot size to hint firmware to do necessary copy */
657 	*size = sizeof(*cf_slot) + cmd_len;
658 	return 0;
659 }
660 
661 static int
aie2_cmdlist_fill_dpu(struct amdxdna_gem_obj * cmd_bo,void * slot,size_t * size)662 aie2_cmdlist_fill_dpu(struct amdxdna_gem_obj *cmd_bo, void *slot, size_t *size)
663 {
664 	struct cmd_chain_slot_dpu *dpu_slot = slot;
665 	struct amdxdna_cmd_start_npu *sn;
666 	u32 cmd_len;
667 	u32 arg_sz;
668 
669 	sn = amdxdna_cmd_get_payload(cmd_bo, &cmd_len);
670 	arg_sz = cmd_len - sizeof(*sn);
671 	if (cmd_len < sizeof(*sn) || arg_sz > MAX_DPU_ARGS_SIZE)
672 		return -EINVAL;
673 
674 	if (*size < sizeof(*dpu_slot) + arg_sz)
675 		return -EINVAL;
676 
677 	dpu_slot->cu_idx = amdxdna_cmd_get_cu_idx(cmd_bo);
678 	if (dpu_slot->cu_idx == INVALID_CU_IDX)
679 		return -EINVAL;
680 
681 	dpu_slot->inst_buf_addr = sn->buffer;
682 	dpu_slot->inst_size = sn->buffer_size;
683 	dpu_slot->inst_prop_cnt = sn->prop_count;
684 	dpu_slot->arg_cnt = arg_sz / sizeof(u32);
685 	memcpy(dpu_slot->args, sn->prop_args, arg_sz);
686 
687 	/* Accurate slot size to hint firmware to do necessary copy */
688 	*size = sizeof(*dpu_slot) + arg_sz;
689 	return 0;
690 }
691 
aie2_cmdlist_unsupp(struct amdxdna_gem_obj * cmd_bo,void * slot,size_t * size)692 static int aie2_cmdlist_unsupp(struct amdxdna_gem_obj *cmd_bo, void *slot, size_t *size)
693 {
694 	return -EOPNOTSUPP;
695 }
696 
aie2_get_chain_msg_op(u32 cmd_op)697 static u32 aie2_get_chain_msg_op(u32 cmd_op)
698 {
699 	switch (cmd_op) {
700 	case ERT_START_CU:
701 		return MSG_OP_CHAIN_EXEC_BUFFER_CF;
702 	case ERT_START_NPU:
703 		return MSG_OP_CHAIN_EXEC_DPU;
704 	default:
705 		break;
706 	}
707 
708 	return MSG_OP_MAX_OPCODE;
709 }
710 
711 static struct aie2_exec_msg_ops legacy_exec_message_ops = {
712 	.init_cu_req = aie2_init_exec_cu_req,
713 	.init_dpu_req = aie2_init_exec_dpu_req,
714 	.init_chain_req = aie2_init_exec_chain_req,
715 	.fill_cf_slot = aie2_cmdlist_fill_cf,
716 	.fill_dpu_slot = aie2_cmdlist_fill_dpu,
717 	.fill_preempt_slot = aie2_cmdlist_unsupp,
718 	.fill_elf_slot = aie2_cmdlist_unsupp,
719 	.get_chain_msg_op = aie2_get_chain_msg_op,
720 };
721 
722 static int
aie2_cmdlist_fill_npu_cf(struct amdxdna_gem_obj * cmd_bo,void * slot,size_t * size)723 aie2_cmdlist_fill_npu_cf(struct amdxdna_gem_obj *cmd_bo, void *slot, size_t *size)
724 {
725 	struct cmd_chain_slot_npu *npu_slot = slot;
726 	u32 cmd_len;
727 	void *cmd;
728 
729 	cmd = amdxdna_cmd_get_payload(cmd_bo, &cmd_len);
730 	if (*size < sizeof(*npu_slot) + cmd_len)
731 		return -EINVAL;
732 
733 	memset(npu_slot, 0, sizeof(*npu_slot));
734 	npu_slot->cu_idx = amdxdna_cmd_get_cu_idx(cmd_bo);
735 	if (npu_slot->cu_idx == INVALID_CU_IDX)
736 		return -EINVAL;
737 
738 	npu_slot->type = EXEC_NPU_TYPE_NON_ELF;
739 	npu_slot->arg_cnt = cmd_len / sizeof(u32);
740 	memcpy(npu_slot->args, cmd, cmd_len);
741 
742 	*size = sizeof(*npu_slot) + cmd_len;
743 	return 0;
744 }
745 
746 static int
aie2_cmdlist_fill_npu_dpu(struct amdxdna_gem_obj * cmd_bo,void * slot,size_t * size)747 aie2_cmdlist_fill_npu_dpu(struct amdxdna_gem_obj *cmd_bo, void *slot, size_t *size)
748 {
749 	struct cmd_chain_slot_npu *npu_slot = slot;
750 	struct amdxdna_cmd_start_npu *sn;
751 	u32 cmd_len;
752 	u32 arg_sz;
753 
754 	sn = amdxdna_cmd_get_payload(cmd_bo, &cmd_len);
755 	arg_sz = cmd_len - sizeof(*sn);
756 	if (cmd_len < sizeof(*sn) || arg_sz > MAX_NPU_ARGS_SIZE)
757 		return -EINVAL;
758 
759 	if (*size < sizeof(*npu_slot) + arg_sz)
760 		return -EINVAL;
761 
762 	memset(npu_slot, 0, sizeof(*npu_slot));
763 	npu_slot->cu_idx = amdxdna_cmd_get_cu_idx(cmd_bo);
764 	if (npu_slot->cu_idx == INVALID_CU_IDX)
765 		return -EINVAL;
766 
767 	npu_slot->type = EXEC_NPU_TYPE_PARTIAL_ELF;
768 	npu_slot->inst_buf_addr = sn->buffer;
769 	npu_slot->inst_size = sn->buffer_size;
770 	npu_slot->inst_prop_cnt = sn->prop_count;
771 	npu_slot->arg_cnt = arg_sz / sizeof(u32);
772 	memcpy(npu_slot->args, sn->prop_args, arg_sz);
773 
774 	*size = sizeof(*npu_slot) + arg_sz;
775 	return 0;
776 }
777 
778 static int
aie2_cmdlist_fill_npu_preempt(struct amdxdna_gem_obj * cmd_bo,void * slot,size_t * size)779 aie2_cmdlist_fill_npu_preempt(struct amdxdna_gem_obj *cmd_bo, void *slot, size_t *size)
780 {
781 	struct cmd_chain_slot_npu *npu_slot = slot;
782 	struct amdxdna_cmd_preempt_data *pd;
783 	u32 cmd_len;
784 	u32 arg_sz;
785 
786 	pd = amdxdna_cmd_get_payload(cmd_bo, &cmd_len);
787 	arg_sz = cmd_len - sizeof(*pd);
788 	if (cmd_len < sizeof(*pd) || arg_sz > MAX_NPU_ARGS_SIZE)
789 		return -EINVAL;
790 
791 	if (*size < sizeof(*npu_slot) + arg_sz)
792 		return -EINVAL;
793 
794 	memset(npu_slot, 0, sizeof(*npu_slot));
795 	npu_slot->cu_idx = amdxdna_cmd_get_cu_idx(cmd_bo);
796 	if (npu_slot->cu_idx == INVALID_CU_IDX)
797 		return -EINVAL;
798 
799 	npu_slot->type = EXEC_NPU_TYPE_PREEMPT;
800 	npu_slot->inst_buf_addr = pd->inst_buf;
801 	npu_slot->save_buf_addr = pd->save_buf;
802 	npu_slot->restore_buf_addr = pd->restore_buf;
803 	npu_slot->inst_size = pd->inst_size;
804 	npu_slot->save_size = pd->save_size;
805 	npu_slot->restore_size = pd->restore_size;
806 	npu_slot->inst_prop_cnt = pd->inst_prop_cnt;
807 	npu_slot->arg_cnt = arg_sz / sizeof(u32);
808 	memcpy(npu_slot->args, pd->prop_args, arg_sz);
809 
810 	*size = sizeof(*npu_slot) + arg_sz;
811 	return 0;
812 }
813 
814 static int
aie2_cmdlist_fill_npu_elf(struct amdxdna_gem_obj * cmd_bo,void * slot,size_t * size)815 aie2_cmdlist_fill_npu_elf(struct amdxdna_gem_obj *cmd_bo, void *slot, size_t *size)
816 {
817 	struct cmd_chain_slot_npu *npu_slot = slot;
818 	struct amdxdna_cmd_preempt_data *pd;
819 	u32 cmd_len;
820 	u32 arg_sz;
821 
822 	pd = amdxdna_cmd_get_payload(cmd_bo, &cmd_len);
823 	arg_sz = cmd_len - sizeof(*pd);
824 	if (cmd_len < sizeof(*pd) || arg_sz > MAX_NPU_ARGS_SIZE)
825 		return -EINVAL;
826 
827 	if (*size < sizeof(*npu_slot) + arg_sz)
828 		return -EINVAL;
829 
830 	memset(npu_slot, 0, sizeof(*npu_slot));
831 	npu_slot->type = EXEC_NPU_TYPE_ELF;
832 	npu_slot->inst_buf_addr = pd->inst_buf;
833 	npu_slot->save_buf_addr = pd->save_buf;
834 	npu_slot->restore_buf_addr = pd->restore_buf;
835 	npu_slot->inst_size = pd->inst_size;
836 	npu_slot->save_size = pd->save_size;
837 	npu_slot->restore_size = pd->restore_size;
838 	npu_slot->inst_prop_cnt = pd->inst_prop_cnt;
839 	npu_slot->arg_cnt = 1;
840 	npu_slot->args[0] = AIE2_EXEC_BUFFER_KERNEL_OP_TXN;
841 
842 	*size = struct_size(npu_slot, args, npu_slot->arg_cnt);
843 	return 0;
844 }
845 
aie2_get_npu_chain_msg_op(u32 cmd_op)846 static u32 aie2_get_npu_chain_msg_op(u32 cmd_op)
847 {
848 	return MSG_OP_CHAIN_EXEC_NPU;
849 }
850 
851 static struct aie2_exec_msg_ops npu_exec_message_ops = {
852 	.init_cu_req = aie2_init_exec_cu_req,
853 	.init_dpu_req = aie2_init_exec_dpu_req,
854 	.init_chain_req = aie2_init_npu_chain_req,
855 	.fill_cf_slot = aie2_cmdlist_fill_npu_cf,
856 	.fill_dpu_slot = aie2_cmdlist_fill_npu_dpu,
857 	.fill_preempt_slot = aie2_cmdlist_fill_npu_preempt,
858 	.fill_elf_slot = aie2_cmdlist_fill_npu_elf,
859 	.get_chain_msg_op = aie2_get_npu_chain_msg_op,
860 };
861 
aie2_init_exec_req(void * req,struct amdxdna_gem_obj * cmd_abo,size_t * size,u32 * msg_op)862 static int aie2_init_exec_req(void *req, struct amdxdna_gem_obj *cmd_abo,
863 			      size_t *size, u32 *msg_op)
864 {
865 	struct amdxdna_dev *xdna = cmd_abo->client->xdna;
866 	int ret;
867 	u32 op;
868 
869 
870 	op = amdxdna_cmd_get_op(cmd_abo);
871 	switch (op) {
872 	case ERT_START_CU:
873 		ret = EXEC_MSG_OPS(xdna)->init_cu_req(cmd_abo, req, size, msg_op);
874 		if (ret) {
875 			XDNA_DBG(xdna, "Init CU req failed ret %d", ret);
876 			return ret;
877 		}
878 		break;
879 	case ERT_START_NPU:
880 		ret = EXEC_MSG_OPS(xdna)->init_dpu_req(cmd_abo, req, size, msg_op);
881 		if (ret) {
882 			XDNA_DBG(xdna, "Init DPU req failed ret %d", ret);
883 			return ret;
884 		}
885 
886 		break;
887 	default:
888 		XDNA_ERR(xdna, "Unsupported op %d", op);
889 		ret = -EOPNOTSUPP;
890 		break;
891 	}
892 
893 	return ret;
894 }
895 
896 static int
aie2_cmdlist_fill_slot(void * slot,struct amdxdna_gem_obj * cmd_abo,size_t * size,u32 * cmd_op)897 aie2_cmdlist_fill_slot(void *slot, struct amdxdna_gem_obj *cmd_abo,
898 		       size_t *size, u32 *cmd_op)
899 {
900 	struct amdxdna_dev *xdna = cmd_abo->client->xdna;
901 	int ret;
902 	u32 op;
903 
904 	op = amdxdna_cmd_get_op(cmd_abo);
905 	if (*cmd_op == ERT_INVALID_CMD)
906 		*cmd_op = op;
907 	else if (op != *cmd_op)
908 		return -EINVAL;
909 
910 	switch (op) {
911 	case ERT_START_CU:
912 		ret = EXEC_MSG_OPS(xdna)->fill_cf_slot(cmd_abo, slot, size);
913 		break;
914 	case ERT_START_NPU:
915 		ret = EXEC_MSG_OPS(xdna)->fill_dpu_slot(cmd_abo, slot, size);
916 		break;
917 	case ERT_START_NPU_PREEMPT:
918 		if (!AIE2_FEATURE_ON(xdna->dev_handle, AIE2_PREEMPT))
919 			return -EOPNOTSUPP;
920 		ret = EXEC_MSG_OPS(xdna)->fill_preempt_slot(cmd_abo, slot, size);
921 		break;
922 	case ERT_START_NPU_PREEMPT_ELF:
923 		if (!AIE2_FEATURE_ON(xdna->dev_handle, AIE2_PREEMPT))
924 			return -EOPNOTSUPP;
925 		ret = EXEC_MSG_OPS(xdna)->fill_elf_slot(cmd_abo, slot, size);
926 		break;
927 	default:
928 		XDNA_INFO(xdna, "Unsupported op %d", op);
929 		ret = -EOPNOTSUPP;
930 		break;
931 	}
932 
933 	return ret;
934 }
935 
aie2_msg_init(struct amdxdna_dev_hdl * ndev)936 void aie2_msg_init(struct amdxdna_dev_hdl *ndev)
937 {
938 	if (AIE2_FEATURE_ON(ndev, AIE2_NPU_COMMAND))
939 		ndev->exec_msg_ops = &npu_exec_message_ops;
940 	else
941 		ndev->exec_msg_ops = &legacy_exec_message_ops;
942 }
943 
aie2_destroy_mgmt_chann(struct amdxdna_dev_hdl * ndev)944 void aie2_destroy_mgmt_chann(struct amdxdna_dev_hdl *ndev)
945 {
946 	struct amdxdna_dev *xdna = ndev->xdna;
947 
948 	drm_WARN_ON(&xdna->ddev, !mutex_is_locked(&xdna->dev_lock));
949 
950 	if (!ndev->mgmt_chann)
951 		return;
952 
953 	xdna_mailbox_stop_channel(ndev->mgmt_chann);
954 	xdna_mailbox_free_channel(ndev->mgmt_chann);
955 	ndev->mgmt_chann = NULL;
956 }
957 
958 static inline struct amdxdna_gem_obj *
aie2_cmdlist_get_cmd_buf(struct amdxdna_sched_job * job)959 aie2_cmdlist_get_cmd_buf(struct amdxdna_sched_job *job)
960 {
961 	int idx = get_job_idx(job->seq);
962 
963 	return job->hwctx->priv->cmd_buf[idx];
964 }
965 
aie2_execbuf(struct amdxdna_hwctx * hwctx,struct amdxdna_sched_job * job,int (* notify_cb)(void *,void __iomem *,size_t))966 int aie2_execbuf(struct amdxdna_hwctx *hwctx, struct amdxdna_sched_job *job,
967 		 int (*notify_cb)(void *, void __iomem *, size_t))
968 {
969 	struct mailbox_channel *chann = hwctx->priv->mbox_chann;
970 	struct amdxdna_dev *xdna = hwctx->client->xdna;
971 	struct amdxdna_gem_obj *cmd_abo = job->cmd_bo;
972 	struct xdna_mailbox_msg msg;
973 	union exec_req req;
974 	int ret;
975 
976 	if (!chann)
977 		return -ENODEV;
978 
979 	ret = aie2_init_exec_req(&req, cmd_abo, &msg.send_size, &msg.opcode);
980 	if (ret)
981 		return ret;
982 
983 	msg.handle = job;
984 	msg.notify_cb = notify_cb;
985 	msg.send_data = (u8 *)&req;
986 	print_hex_dump_debug("cmd: ", DUMP_PREFIX_OFFSET, 16, 4, &req,
987 			     0x40, false);
988 
989 	ret = xdna_mailbox_send_msg(chann, &msg, TX_TIMEOUT);
990 	if (ret) {
991 		XDNA_ERR(xdna, "Send message failed");
992 		return ret;
993 	}
994 
995 	return 0;
996 }
997 
aie2_cmdlist_multi_execbuf(struct amdxdna_hwctx * hwctx,struct amdxdna_sched_job * job,int (* notify_cb)(void *,void __iomem *,size_t))998 int aie2_cmdlist_multi_execbuf(struct amdxdna_hwctx *hwctx,
999 			       struct amdxdna_sched_job *job,
1000 			       int (*notify_cb)(void *, void __iomem *, size_t))
1001 {
1002 	struct amdxdna_gem_obj *cmdbuf_abo = aie2_cmdlist_get_cmd_buf(job);
1003 	struct mailbox_channel *chann = hwctx->priv->mbox_chann;
1004 	struct amdxdna_client *client = hwctx->client;
1005 	struct amdxdna_gem_obj *cmd_abo = job->cmd_bo;
1006 	void *cmd_buf = amdxdna_gem_vmap(cmdbuf_abo);
1007 	struct amdxdna_dev *xdna = client->xdna;
1008 	struct amdxdna_cmd_chain *payload;
1009 	struct xdna_mailbox_msg msg;
1010 	union exec_chain_req req;
1011 	u32 payload_len, ccnt;
1012 	u32 offset = 0;
1013 	size_t size;
1014 	int ret;
1015 	u32 op;
1016 	u32 i;
1017 
1018 	if (!cmd_buf)
1019 		return -ENOMEM;
1020 
1021 	op = amdxdna_cmd_get_op(cmd_abo);
1022 	payload = amdxdna_cmd_get_payload(cmd_abo, &payload_len);
1023 	if (op != ERT_CMD_CHAIN) {
1024 		XDNA_DBG(xdna, "Invalid op code %d", op);
1025 		return -EINVAL;
1026 	}
1027 
1028 	if (!payload) {
1029 		XDNA_DBG(xdna, "Failed to get command payload");
1030 		return -EINVAL;
1031 	}
1032 
1033 	ccnt = payload->command_count;
1034 	if (payload_len < struct_size(payload, data, ccnt)) {
1035 		XDNA_DBG(xdna, "Invalid command count %d", ccnt);
1036 		return -EINVAL;
1037 	}
1038 
1039 	op = ERT_INVALID_CMD;
1040 	for (i = 0; i < ccnt; i++) {
1041 		u32 boh = (u32)(payload->data[i]);
1042 		struct amdxdna_gem_obj *abo;
1043 
1044 		abo = amdxdna_gem_get_obj(client, boh, AMDXDNA_BO_SHARE);
1045 		if (!abo) {
1046 			XDNA_ERR(xdna, "Failed to find cmd BO %d", boh);
1047 			return -ENOENT;
1048 		}
1049 
1050 		size = cmdbuf_abo->mem.size - offset;
1051 		ret = aie2_cmdlist_fill_slot(cmd_buf + offset, abo, &size, &op);
1052 		amdxdna_gem_put_obj(abo);
1053 		if (ret)
1054 			return ret;
1055 
1056 		offset += size;
1057 	}
1058 
1059 	XDNA_DBG(xdna, "Total %d commands:", ccnt);
1060 	print_hex_dump_debug("cmdbufs: ", DUMP_PREFIX_OFFSET, 16, 4,
1061 			     cmd_buf, offset, false);
1062 
1063 	msg.opcode = EXEC_MSG_OPS(xdna)->get_chain_msg_op(op);
1064 	if (msg.opcode == MSG_OP_MAX_OPCODE)
1065 		return -EOPNOTSUPP;
1066 
1067 	/* The offset is the accumulated total size of the cmd buffer */
1068 	EXEC_MSG_OPS(xdna)->init_chain_req(&req, amdxdna_gem_dev_addr(cmdbuf_abo),
1069 					   offset, ccnt);
1070 	drm_clflush_virt_range(cmd_buf, offset);
1071 
1072 	msg.handle = job;
1073 	msg.notify_cb = notify_cb;
1074 	msg.send_data = (u8 *)&req;
1075 	msg.send_size = sizeof(req);
1076 	print_hex_dump_debug("cmdlist msg: ", DUMP_PREFIX_OFFSET, 16, 4,
1077 			     &req, msg.send_size, false);
1078 	ret = xdna_mailbox_send_msg(chann, &msg, TX_TIMEOUT);
1079 	if (ret) {
1080 		XDNA_ERR(xdna, "Send message failed");
1081 		return ret;
1082 	}
1083 
1084 	return 0;
1085 }
1086 
aie2_cmdlist_single_execbuf(struct amdxdna_hwctx * hwctx,struct amdxdna_sched_job * job,int (* notify_cb)(void *,void __iomem *,size_t))1087 int aie2_cmdlist_single_execbuf(struct amdxdna_hwctx *hwctx,
1088 				struct amdxdna_sched_job *job,
1089 				int (*notify_cb)(void *, void __iomem *, size_t))
1090 {
1091 	struct amdxdna_gem_obj *cmdbuf_abo = aie2_cmdlist_get_cmd_buf(job);
1092 	struct mailbox_channel *chann = hwctx->priv->mbox_chann;
1093 	struct amdxdna_dev *xdna = hwctx->client->xdna;
1094 	struct amdxdna_gem_obj *cmd_abo = job->cmd_bo;
1095 	void *cmd_buf = amdxdna_gem_vmap(cmdbuf_abo);
1096 	struct xdna_mailbox_msg msg;
1097 	union exec_chain_req req;
1098 	u32 op = ERT_INVALID_CMD;
1099 	size_t size;
1100 	int ret;
1101 
1102 	if (!cmd_buf)
1103 		return -ENOMEM;
1104 
1105 	size = cmdbuf_abo->mem.size;
1106 	ret = aie2_cmdlist_fill_slot(cmd_buf, cmd_abo, &size, &op);
1107 	if (ret)
1108 		return ret;
1109 
1110 	print_hex_dump_debug("cmdbuf: ", DUMP_PREFIX_OFFSET, 16, 4, cmd_buf, size, false);
1111 
1112 	msg.opcode = EXEC_MSG_OPS(xdna)->get_chain_msg_op(op);
1113 	if (msg.opcode == MSG_OP_MAX_OPCODE)
1114 		return -EOPNOTSUPP;
1115 
1116 	EXEC_MSG_OPS(xdna)->init_chain_req(&req, amdxdna_gem_dev_addr(cmdbuf_abo), size, 1);
1117 	drm_clflush_virt_range(cmd_buf, size);
1118 
1119 	msg.handle = job;
1120 	msg.notify_cb = notify_cb;
1121 	msg.send_data = (u8 *)&req;
1122 	msg.send_size = sizeof(req);
1123 	print_hex_dump_debug("cmdlist msg: ", DUMP_PREFIX_OFFSET, 16, 4,
1124 			     &req, msg.send_size, false);
1125 	ret = xdna_mailbox_send_msg(chann, &msg, TX_TIMEOUT);
1126 	if (ret) {
1127 		XDNA_ERR(hwctx->client->xdna, "Send message failed");
1128 		return ret;
1129 	}
1130 
1131 	return 0;
1132 }
1133 
aie2_sync_bo(struct amdxdna_hwctx * hwctx,struct amdxdna_sched_job * job,int (* notify_cb)(void *,void __iomem *,size_t))1134 int aie2_sync_bo(struct amdxdna_hwctx *hwctx, struct amdxdna_sched_job *job,
1135 		 int (*notify_cb)(void *, void __iomem *, size_t))
1136 {
1137 	struct mailbox_channel *chann = hwctx->priv->mbox_chann;
1138 	struct amdxdna_gem_obj *abo = to_xdna_obj(job->bos[0]);
1139 	struct amdxdna_dev *xdna = hwctx->client->xdna;
1140 	struct xdna_mailbox_msg msg;
1141 	struct sync_bo_req req;
1142 	int ret = 0;
1143 
1144 	req.src_addr = 0;
1145 	req.dst_addr = amdxdna_dev_bo_offset(abo);
1146 	req.size = abo->mem.size;
1147 
1148 	/* Device to Host */
1149 	req.type = FIELD_PREP(AIE2_MSG_SYNC_BO_SRC_TYPE, SYNC_BO_DEV_MEM) |
1150 		FIELD_PREP(AIE2_MSG_SYNC_BO_DST_TYPE, SYNC_BO_HOST_MEM);
1151 
1152 	XDNA_DBG(xdna, "sync %d bytes src(0x%llx) to dst(0x%llx) completed",
1153 		 req.size, req.src_addr, req.dst_addr);
1154 
1155 	msg.handle = job;
1156 	msg.notify_cb = notify_cb;
1157 	msg.send_data = (u8 *)&req;
1158 	msg.send_size = sizeof(req);
1159 	msg.opcode = MSG_OP_SYNC_BO;
1160 
1161 	ret = xdna_mailbox_send_msg(chann, &msg, TX_TIMEOUT);
1162 	if (ret) {
1163 		XDNA_ERR(xdna, "Send message failed");
1164 		return ret;
1165 	}
1166 
1167 	return 0;
1168 }
1169 
aie2_config_debug_bo(struct amdxdna_hwctx * hwctx,struct amdxdna_sched_job * job,int (* notify_cb)(void *,void __iomem *,size_t))1170 int aie2_config_debug_bo(struct amdxdna_hwctx *hwctx, struct amdxdna_sched_job *job,
1171 			 int (*notify_cb)(void *, void __iomem *, size_t))
1172 {
1173 	struct mailbox_channel *chann = hwctx->priv->mbox_chann;
1174 	struct amdxdna_gem_obj *abo = to_xdna_obj(job->bos[0]);
1175 	struct amdxdna_dev *xdna = hwctx->client->xdna;
1176 	struct config_debug_bo_req req;
1177 	struct xdna_mailbox_msg msg;
1178 
1179 	if (job->drv_cmd->opcode == ATTACH_DEBUG_BO)
1180 		req.config = DEBUG_BO_REGISTER;
1181 	else
1182 		req.config = DEBUG_BO_UNREGISTER;
1183 
1184 	req.offset = amdxdna_dev_bo_offset(abo);
1185 	req.size = abo->mem.size;
1186 
1187 	XDNA_DBG(xdna, "offset 0x%llx size 0x%llx config %d",
1188 		 req.offset, req.size, req.config);
1189 
1190 	msg.handle = job;
1191 	msg.notify_cb = notify_cb;
1192 	msg.send_data = (u8 *)&req;
1193 	msg.send_size = sizeof(req);
1194 	msg.opcode = MSG_OP_CONFIG_DEBUG_BO;
1195 
1196 	return xdna_mailbox_send_msg(chann, &msg, TX_TIMEOUT);
1197 }
1198 
aie2_query_app_health(struct amdxdna_dev_hdl * ndev,u32 context_id,struct app_health_report * report)1199 int aie2_query_app_health(struct amdxdna_dev_hdl *ndev, u32 context_id,
1200 			  struct app_health_report *report)
1201 {
1202 	DECLARE_AIE2_MSG(get_app_health, MSG_OP_GET_APP_HEALTH);
1203 	struct amdxdna_dev *xdna = ndev->xdna;
1204 	struct app_health_report *buf;
1205 	dma_addr_t dma_addr;
1206 	u32 buf_size;
1207 	int ret;
1208 
1209 	if (!AIE2_FEATURE_ON(ndev, AIE2_APP_HEALTH)) {
1210 		XDNA_DBG(xdna, "App health feature not supported");
1211 		return -EOPNOTSUPP;
1212 	}
1213 
1214 	buf_size = sizeof(*report);
1215 	buf = aie2_alloc_msg_buffer(ndev, &buf_size, &dma_addr);
1216 	if (IS_ERR(buf)) {
1217 		XDNA_ERR(xdna, "Failed to allocate buffer for app health");
1218 		return PTR_ERR(buf);
1219 	}
1220 
1221 	req.buf_addr = dma_addr;
1222 	req.context_id = context_id;
1223 	req.buf_size = buf_size;
1224 
1225 	drm_clflush_virt_range(buf, sizeof(*report));
1226 	ret = aie2_send_mgmt_msg_wait(ndev, &msg);
1227 	if (ret) {
1228 		XDNA_ERR(xdna, "Get app health failed, ret %d status 0x%x", ret, resp.status);
1229 		goto free_buf;
1230 	}
1231 
1232 	/* Copy the report to caller's buffer */
1233 	memcpy(report, buf, sizeof(*report));
1234 
1235 free_buf:
1236 	aie2_free_msg_buffer(ndev, buf_size, buf, dma_addr);
1237 	return ret;
1238 }
1239