xref: /openbmc/linux/drivers/accel/ivpu/ivpu_jsm_msg.c (revision c900529f3d9161bfde5cca0754f83b4d3c3e0220)
15d7422cfSJacek Lawrynowicz // SPDX-License-Identifier: GPL-2.0-only
25d7422cfSJacek Lawrynowicz /*
35d7422cfSJacek Lawrynowicz  * Copyright (C) 2020-2023 Intel Corporation
45d7422cfSJacek Lawrynowicz  */
55d7422cfSJacek Lawrynowicz 
65d7422cfSJacek Lawrynowicz #include "ivpu_drv.h"
75d7422cfSJacek Lawrynowicz #include "ivpu_ipc.h"
85d7422cfSJacek Lawrynowicz #include "ivpu_jsm_msg.h"
95d7422cfSJacek Lawrynowicz 
ivpu_jsm_register_db(struct ivpu_device * vdev,u32 ctx_id,u32 db_id,u64 jobq_base,u32 jobq_size)105d7422cfSJacek Lawrynowicz int ivpu_jsm_register_db(struct ivpu_device *vdev, u32 ctx_id, u32 db_id,
115d7422cfSJacek Lawrynowicz 			 u64 jobq_base, u32 jobq_size)
125d7422cfSJacek Lawrynowicz {
135d7422cfSJacek Lawrynowicz 	struct vpu_jsm_msg req = { .type = VPU_JSM_MSG_REGISTER_DB };
145d7422cfSJacek Lawrynowicz 	struct vpu_jsm_msg resp;
155d7422cfSJacek Lawrynowicz 	int ret = 0;
165d7422cfSJacek Lawrynowicz 
175d7422cfSJacek Lawrynowicz 	req.payload.register_db.db_idx = db_id;
185d7422cfSJacek Lawrynowicz 	req.payload.register_db.jobq_base = jobq_base;
195d7422cfSJacek Lawrynowicz 	req.payload.register_db.jobq_size = jobq_size;
205d7422cfSJacek Lawrynowicz 	req.payload.register_db.host_ssid = ctx_id;
215d7422cfSJacek Lawrynowicz 
225d7422cfSJacek Lawrynowicz 	ret = ivpu_ipc_send_receive(vdev, &req, VPU_JSM_MSG_REGISTER_DB_DONE, &resp,
235d7422cfSJacek Lawrynowicz 				    VPU_IPC_CHAN_ASYNC_CMD, vdev->timeout.jsm);
245d7422cfSJacek Lawrynowicz 	if (ret) {
255d7422cfSJacek Lawrynowicz 		ivpu_err(vdev, "Failed to register doorbell %d: %d\n", db_id, ret);
265d7422cfSJacek Lawrynowicz 		return ret;
275d7422cfSJacek Lawrynowicz 	}
285d7422cfSJacek Lawrynowicz 
295d7422cfSJacek Lawrynowicz 	ivpu_dbg(vdev, JSM, "Doorbell %d registered to context %d\n", db_id, ctx_id);
305d7422cfSJacek Lawrynowicz 
315d7422cfSJacek Lawrynowicz 	return 0;
325d7422cfSJacek Lawrynowicz }
335d7422cfSJacek Lawrynowicz 
ivpu_jsm_unregister_db(struct ivpu_device * vdev,u32 db_id)345d7422cfSJacek Lawrynowicz int ivpu_jsm_unregister_db(struct ivpu_device *vdev, u32 db_id)
355d7422cfSJacek Lawrynowicz {
365d7422cfSJacek Lawrynowicz 	struct vpu_jsm_msg req = { .type = VPU_JSM_MSG_UNREGISTER_DB };
375d7422cfSJacek Lawrynowicz 	struct vpu_jsm_msg resp;
385d7422cfSJacek Lawrynowicz 	int ret = 0;
395d7422cfSJacek Lawrynowicz 
405d7422cfSJacek Lawrynowicz 	req.payload.unregister_db.db_idx = db_id;
415d7422cfSJacek Lawrynowicz 
425d7422cfSJacek Lawrynowicz 	ret = ivpu_ipc_send_receive(vdev, &req, VPU_JSM_MSG_UNREGISTER_DB_DONE, &resp,
435d7422cfSJacek Lawrynowicz 				    VPU_IPC_CHAN_ASYNC_CMD, vdev->timeout.jsm);
445d7422cfSJacek Lawrynowicz 	if (ret) {
455d7422cfSJacek Lawrynowicz 		ivpu_warn(vdev, "Failed to unregister doorbell %d: %d\n", db_id, ret);
465d7422cfSJacek Lawrynowicz 		return ret;
475d7422cfSJacek Lawrynowicz 	}
485d7422cfSJacek Lawrynowicz 
495d7422cfSJacek Lawrynowicz 	ivpu_dbg(vdev, JSM, "Doorbell %d unregistered\n", db_id);
505d7422cfSJacek Lawrynowicz 
515d7422cfSJacek Lawrynowicz 	return 0;
525d7422cfSJacek Lawrynowicz }
535d7422cfSJacek Lawrynowicz 
ivpu_jsm_get_heartbeat(struct ivpu_device * vdev,u32 engine,u64 * heartbeat)545d7422cfSJacek Lawrynowicz int ivpu_jsm_get_heartbeat(struct ivpu_device *vdev, u32 engine, u64 *heartbeat)
555d7422cfSJacek Lawrynowicz {
565d7422cfSJacek Lawrynowicz 	struct vpu_jsm_msg req = { .type = VPU_JSM_MSG_QUERY_ENGINE_HB };
575d7422cfSJacek Lawrynowicz 	struct vpu_jsm_msg resp;
585d7422cfSJacek Lawrynowicz 	int ret;
595d7422cfSJacek Lawrynowicz 
605d7422cfSJacek Lawrynowicz 	if (engine > VPU_ENGINE_COPY)
615d7422cfSJacek Lawrynowicz 		return -EINVAL;
625d7422cfSJacek Lawrynowicz 
635d7422cfSJacek Lawrynowicz 	req.payload.query_engine_hb.engine_idx = engine;
645d7422cfSJacek Lawrynowicz 
655d7422cfSJacek Lawrynowicz 	ret = ivpu_ipc_send_receive(vdev, &req, VPU_JSM_MSG_QUERY_ENGINE_HB_DONE, &resp,
665d7422cfSJacek Lawrynowicz 				    VPU_IPC_CHAN_ASYNC_CMD, vdev->timeout.jsm);
675d7422cfSJacek Lawrynowicz 	if (ret) {
685d7422cfSJacek Lawrynowicz 		ivpu_err(vdev, "Failed to get heartbeat from engine %d: %d\n", engine, ret);
695d7422cfSJacek Lawrynowicz 		return ret;
705d7422cfSJacek Lawrynowicz 	}
715d7422cfSJacek Lawrynowicz 
725d7422cfSJacek Lawrynowicz 	*heartbeat = resp.payload.query_engine_hb_done.heartbeat;
735d7422cfSJacek Lawrynowicz 	return ret;
745d7422cfSJacek Lawrynowicz }
755d7422cfSJacek Lawrynowicz 
ivpu_jsm_reset_engine(struct ivpu_device * vdev,u32 engine)765d7422cfSJacek Lawrynowicz int ivpu_jsm_reset_engine(struct ivpu_device *vdev, u32 engine)
775d7422cfSJacek Lawrynowicz {
785d7422cfSJacek Lawrynowicz 	struct vpu_jsm_msg req = { .type = VPU_JSM_MSG_ENGINE_RESET };
795d7422cfSJacek Lawrynowicz 	struct vpu_jsm_msg resp;
805d7422cfSJacek Lawrynowicz 	int ret;
815d7422cfSJacek Lawrynowicz 
825d7422cfSJacek Lawrynowicz 	if (engine > VPU_ENGINE_COPY)
835d7422cfSJacek Lawrynowicz 		return -EINVAL;
845d7422cfSJacek Lawrynowicz 
855d7422cfSJacek Lawrynowicz 	req.payload.engine_reset.engine_idx = engine;
865d7422cfSJacek Lawrynowicz 
875d7422cfSJacek Lawrynowicz 	ret = ivpu_ipc_send_receive(vdev, &req, VPU_JSM_MSG_ENGINE_RESET_DONE, &resp,
885d7422cfSJacek Lawrynowicz 				    VPU_IPC_CHAN_ASYNC_CMD, vdev->timeout.jsm);
895d7422cfSJacek Lawrynowicz 	if (ret)
905d7422cfSJacek Lawrynowicz 		ivpu_err(vdev, "Failed to reset engine %d: %d\n", engine, ret);
915d7422cfSJacek Lawrynowicz 
925d7422cfSJacek Lawrynowicz 	return ret;
935d7422cfSJacek Lawrynowicz }
945d7422cfSJacek Lawrynowicz 
ivpu_jsm_preempt_engine(struct ivpu_device * vdev,u32 engine,u32 preempt_id)955d7422cfSJacek Lawrynowicz int ivpu_jsm_preempt_engine(struct ivpu_device *vdev, u32 engine, u32 preempt_id)
965d7422cfSJacek Lawrynowicz {
975d7422cfSJacek Lawrynowicz 	struct vpu_jsm_msg req = { .type = VPU_JSM_MSG_ENGINE_PREEMPT };
985d7422cfSJacek Lawrynowicz 	struct vpu_jsm_msg resp;
995d7422cfSJacek Lawrynowicz 	int ret;
1005d7422cfSJacek Lawrynowicz 
1015d7422cfSJacek Lawrynowicz 	if (engine > VPU_ENGINE_COPY)
1025d7422cfSJacek Lawrynowicz 		return -EINVAL;
1035d7422cfSJacek Lawrynowicz 
1045d7422cfSJacek Lawrynowicz 	req.payload.engine_preempt.engine_idx = engine;
1055d7422cfSJacek Lawrynowicz 	req.payload.engine_preempt.preempt_id = preempt_id;
1065d7422cfSJacek Lawrynowicz 
1075d7422cfSJacek Lawrynowicz 	ret = ivpu_ipc_send_receive(vdev, &req, VPU_JSM_MSG_ENGINE_PREEMPT_DONE, &resp,
1085d7422cfSJacek Lawrynowicz 				    VPU_IPC_CHAN_ASYNC_CMD, vdev->timeout.jsm);
1095d7422cfSJacek Lawrynowicz 	if (ret)
1105d7422cfSJacek Lawrynowicz 		ivpu_err(vdev, "Failed to preempt engine %d: %d\n", engine, ret);
1115d7422cfSJacek Lawrynowicz 
1125d7422cfSJacek Lawrynowicz 	return ret;
1135d7422cfSJacek Lawrynowicz }
1145d7422cfSJacek Lawrynowicz 
ivpu_jsm_dyndbg_control(struct ivpu_device * vdev,char * command,size_t size)1155d7422cfSJacek Lawrynowicz int ivpu_jsm_dyndbg_control(struct ivpu_device *vdev, char *command, size_t size)
1165d7422cfSJacek Lawrynowicz {
1175d7422cfSJacek Lawrynowicz 	struct vpu_jsm_msg req = { .type = VPU_JSM_MSG_DYNDBG_CONTROL };
1185d7422cfSJacek Lawrynowicz 	struct vpu_jsm_msg resp;
1195d7422cfSJacek Lawrynowicz 	int ret;
1205d7422cfSJacek Lawrynowicz 
121*4b2fd81fSJustin Stitt 	strscpy(req.payload.dyndbg_control.dyndbg_cmd, command, VPU_DYNDBG_CMD_MAX_LEN);
1225d7422cfSJacek Lawrynowicz 
1235d7422cfSJacek Lawrynowicz 	ret = ivpu_ipc_send_receive(vdev, &req, VPU_JSM_MSG_DYNDBG_CONTROL_RSP, &resp,
1245d7422cfSJacek Lawrynowicz 				    VPU_IPC_CHAN_ASYNC_CMD, vdev->timeout.jsm);
1255d7422cfSJacek Lawrynowicz 	if (ret)
1265d7422cfSJacek Lawrynowicz 		ivpu_warn(vdev, "Failed to send command \"%s\": ret %d\n", command, ret);
1275d7422cfSJacek Lawrynowicz 
1285d7422cfSJacek Lawrynowicz 	return ret;
1295d7422cfSJacek Lawrynowicz }
1305d7422cfSJacek Lawrynowicz 
ivpu_jsm_trace_get_capability(struct ivpu_device * vdev,u32 * trace_destination_mask,u64 * trace_hw_component_mask)1315d7422cfSJacek Lawrynowicz int ivpu_jsm_trace_get_capability(struct ivpu_device *vdev, u32 *trace_destination_mask,
1325d7422cfSJacek Lawrynowicz 				  u64 *trace_hw_component_mask)
1335d7422cfSJacek Lawrynowicz {
1345d7422cfSJacek Lawrynowicz 	struct vpu_jsm_msg req = { .type = VPU_JSM_MSG_TRACE_GET_CAPABILITY };
1355d7422cfSJacek Lawrynowicz 	struct vpu_jsm_msg resp;
1365d7422cfSJacek Lawrynowicz 	int ret;
1375d7422cfSJacek Lawrynowicz 
1385d7422cfSJacek Lawrynowicz 	ret = ivpu_ipc_send_receive(vdev, &req, VPU_JSM_MSG_TRACE_GET_CAPABILITY_RSP, &resp,
1395d7422cfSJacek Lawrynowicz 				    VPU_IPC_CHAN_ASYNC_CMD, vdev->timeout.jsm);
1405d7422cfSJacek Lawrynowicz 	if (ret) {
1415d7422cfSJacek Lawrynowicz 		ivpu_warn(vdev, "Failed to get trace capability: %d\n", ret);
1425d7422cfSJacek Lawrynowicz 		return ret;
1435d7422cfSJacek Lawrynowicz 	}
1445d7422cfSJacek Lawrynowicz 
1455d7422cfSJacek Lawrynowicz 	*trace_destination_mask = resp.payload.trace_capability.trace_destination_mask;
1465d7422cfSJacek Lawrynowicz 	*trace_hw_component_mask = resp.payload.trace_capability.trace_hw_component_mask;
1475d7422cfSJacek Lawrynowicz 
1485d7422cfSJacek Lawrynowicz 	return ret;
1495d7422cfSJacek Lawrynowicz }
1505d7422cfSJacek Lawrynowicz 
ivpu_jsm_trace_set_config(struct ivpu_device * vdev,u32 trace_level,u32 trace_destination_mask,u64 trace_hw_component_mask)1515d7422cfSJacek Lawrynowicz int ivpu_jsm_trace_set_config(struct ivpu_device *vdev, u32 trace_level, u32 trace_destination_mask,
1525d7422cfSJacek Lawrynowicz 			      u64 trace_hw_component_mask)
1535d7422cfSJacek Lawrynowicz {
1545d7422cfSJacek Lawrynowicz 	struct vpu_jsm_msg req = { .type = VPU_JSM_MSG_TRACE_SET_CONFIG };
1555d7422cfSJacek Lawrynowicz 	struct vpu_jsm_msg resp;
1565d7422cfSJacek Lawrynowicz 	int ret;
1575d7422cfSJacek Lawrynowicz 
1585d7422cfSJacek Lawrynowicz 	req.payload.trace_config.trace_level = trace_level;
1595d7422cfSJacek Lawrynowicz 	req.payload.trace_config.trace_destination_mask = trace_destination_mask;
1605d7422cfSJacek Lawrynowicz 	req.payload.trace_config.trace_hw_component_mask = trace_hw_component_mask;
1615d7422cfSJacek Lawrynowicz 
1625d7422cfSJacek Lawrynowicz 	ret = ivpu_ipc_send_receive(vdev, &req, VPU_JSM_MSG_TRACE_SET_CONFIG_RSP, &resp,
1635d7422cfSJacek Lawrynowicz 				    VPU_IPC_CHAN_ASYNC_CMD, vdev->timeout.jsm);
1645d7422cfSJacek Lawrynowicz 	if (ret)
1655d7422cfSJacek Lawrynowicz 		ivpu_warn(vdev, "Failed to set config: %d\n", ret);
1665d7422cfSJacek Lawrynowicz 
1675d7422cfSJacek Lawrynowicz 	return ret;
1685d7422cfSJacek Lawrynowicz }
169dffaa98cSAndrzej Kacprowski 
ivpu_jsm_context_release(struct ivpu_device * vdev,u32 host_ssid)170dffaa98cSAndrzej Kacprowski int ivpu_jsm_context_release(struct ivpu_device *vdev, u32 host_ssid)
171dffaa98cSAndrzej Kacprowski {
172dffaa98cSAndrzej Kacprowski 	struct vpu_jsm_msg req = { .type = VPU_JSM_MSG_SSID_RELEASE };
173dffaa98cSAndrzej Kacprowski 	struct vpu_jsm_msg resp;
174dffaa98cSAndrzej Kacprowski 
175dffaa98cSAndrzej Kacprowski 	req.payload.ssid_release.host_ssid = host_ssid;
176dffaa98cSAndrzej Kacprowski 
177dffaa98cSAndrzej Kacprowski 	return ivpu_ipc_send_receive(vdev, &req, VPU_JSM_MSG_SSID_RELEASE_DONE, &resp,
178dffaa98cSAndrzej Kacprowski 				     VPU_IPC_CHAN_ASYNC_CMD, vdev->timeout.jsm);
179dffaa98cSAndrzej Kacprowski }
180