162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright (C) 2020-2023 Intel Corporation 462306a36Sopenharmony_ci */ 562306a36Sopenharmony_ci 662306a36Sopenharmony_ci#include "ivpu_drv.h" 762306a36Sopenharmony_ci#include "ivpu_ipc.h" 862306a36Sopenharmony_ci#include "ivpu_jsm_msg.h" 962306a36Sopenharmony_ci 1062306a36Sopenharmony_ciint ivpu_jsm_register_db(struct ivpu_device *vdev, u32 ctx_id, u32 db_id, 1162306a36Sopenharmony_ci u64 jobq_base, u32 jobq_size) 1262306a36Sopenharmony_ci{ 1362306a36Sopenharmony_ci struct vpu_jsm_msg req = { .type = VPU_JSM_MSG_REGISTER_DB }; 1462306a36Sopenharmony_ci struct vpu_jsm_msg resp; 1562306a36Sopenharmony_ci int ret = 0; 1662306a36Sopenharmony_ci 1762306a36Sopenharmony_ci req.payload.register_db.db_idx = db_id; 1862306a36Sopenharmony_ci req.payload.register_db.jobq_base = jobq_base; 1962306a36Sopenharmony_ci req.payload.register_db.jobq_size = jobq_size; 2062306a36Sopenharmony_ci req.payload.register_db.host_ssid = ctx_id; 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_ci ret = ivpu_ipc_send_receive(vdev, &req, VPU_JSM_MSG_REGISTER_DB_DONE, &resp, 2362306a36Sopenharmony_ci VPU_IPC_CHAN_ASYNC_CMD, vdev->timeout.jsm); 2462306a36Sopenharmony_ci if (ret) { 2562306a36Sopenharmony_ci ivpu_err(vdev, "Failed to register doorbell %d: %d\n", db_id, ret); 2662306a36Sopenharmony_ci return ret; 2762306a36Sopenharmony_ci } 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_ci ivpu_dbg(vdev, JSM, "Doorbell %d registered to context %d\n", db_id, ctx_id); 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_ci return 0; 3262306a36Sopenharmony_ci} 3362306a36Sopenharmony_ci 3462306a36Sopenharmony_ciint ivpu_jsm_unregister_db(struct ivpu_device *vdev, u32 db_id) 3562306a36Sopenharmony_ci{ 3662306a36Sopenharmony_ci struct vpu_jsm_msg req = { .type = VPU_JSM_MSG_UNREGISTER_DB }; 3762306a36Sopenharmony_ci struct vpu_jsm_msg resp; 3862306a36Sopenharmony_ci int ret = 0; 3962306a36Sopenharmony_ci 4062306a36Sopenharmony_ci req.payload.unregister_db.db_idx = db_id; 4162306a36Sopenharmony_ci 4262306a36Sopenharmony_ci ret = ivpu_ipc_send_receive(vdev, &req, VPU_JSM_MSG_UNREGISTER_DB_DONE, &resp, 4362306a36Sopenharmony_ci VPU_IPC_CHAN_ASYNC_CMD, vdev->timeout.jsm); 4462306a36Sopenharmony_ci if (ret) { 4562306a36Sopenharmony_ci ivpu_warn(vdev, "Failed to unregister doorbell %d: %d\n", db_id, ret); 4662306a36Sopenharmony_ci return ret; 4762306a36Sopenharmony_ci } 4862306a36Sopenharmony_ci 4962306a36Sopenharmony_ci ivpu_dbg(vdev, JSM, "Doorbell %d unregistered\n", db_id); 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_ci return 0; 5262306a36Sopenharmony_ci} 5362306a36Sopenharmony_ci 5462306a36Sopenharmony_ciint ivpu_jsm_get_heartbeat(struct ivpu_device *vdev, u32 engine, u64 *heartbeat) 5562306a36Sopenharmony_ci{ 5662306a36Sopenharmony_ci struct vpu_jsm_msg req = { .type = VPU_JSM_MSG_QUERY_ENGINE_HB }; 5762306a36Sopenharmony_ci struct vpu_jsm_msg resp; 5862306a36Sopenharmony_ci int ret; 5962306a36Sopenharmony_ci 6062306a36Sopenharmony_ci if (engine > VPU_ENGINE_COPY) 6162306a36Sopenharmony_ci return -EINVAL; 6262306a36Sopenharmony_ci 6362306a36Sopenharmony_ci req.payload.query_engine_hb.engine_idx = engine; 6462306a36Sopenharmony_ci 6562306a36Sopenharmony_ci ret = ivpu_ipc_send_receive(vdev, &req, VPU_JSM_MSG_QUERY_ENGINE_HB_DONE, &resp, 6662306a36Sopenharmony_ci VPU_IPC_CHAN_ASYNC_CMD, vdev->timeout.jsm); 6762306a36Sopenharmony_ci if (ret) { 6862306a36Sopenharmony_ci ivpu_err(vdev, "Failed to get heartbeat from engine %d: %d\n", engine, ret); 6962306a36Sopenharmony_ci return ret; 7062306a36Sopenharmony_ci } 7162306a36Sopenharmony_ci 7262306a36Sopenharmony_ci *heartbeat = resp.payload.query_engine_hb_done.heartbeat; 7362306a36Sopenharmony_ci return ret; 7462306a36Sopenharmony_ci} 7562306a36Sopenharmony_ci 7662306a36Sopenharmony_ciint ivpu_jsm_reset_engine(struct ivpu_device *vdev, u32 engine) 7762306a36Sopenharmony_ci{ 7862306a36Sopenharmony_ci struct vpu_jsm_msg req = { .type = VPU_JSM_MSG_ENGINE_RESET }; 7962306a36Sopenharmony_ci struct vpu_jsm_msg resp; 8062306a36Sopenharmony_ci int ret; 8162306a36Sopenharmony_ci 8262306a36Sopenharmony_ci if (engine > VPU_ENGINE_COPY) 8362306a36Sopenharmony_ci return -EINVAL; 8462306a36Sopenharmony_ci 8562306a36Sopenharmony_ci req.payload.engine_reset.engine_idx = engine; 8662306a36Sopenharmony_ci 8762306a36Sopenharmony_ci ret = ivpu_ipc_send_receive(vdev, &req, VPU_JSM_MSG_ENGINE_RESET_DONE, &resp, 8862306a36Sopenharmony_ci VPU_IPC_CHAN_ASYNC_CMD, vdev->timeout.jsm); 8962306a36Sopenharmony_ci if (ret) 9062306a36Sopenharmony_ci ivpu_err(vdev, "Failed to reset engine %d: %d\n", engine, ret); 9162306a36Sopenharmony_ci 9262306a36Sopenharmony_ci return ret; 9362306a36Sopenharmony_ci} 9462306a36Sopenharmony_ci 9562306a36Sopenharmony_ciint ivpu_jsm_preempt_engine(struct ivpu_device *vdev, u32 engine, u32 preempt_id) 9662306a36Sopenharmony_ci{ 9762306a36Sopenharmony_ci struct vpu_jsm_msg req = { .type = VPU_JSM_MSG_ENGINE_PREEMPT }; 9862306a36Sopenharmony_ci struct vpu_jsm_msg resp; 9962306a36Sopenharmony_ci int ret; 10062306a36Sopenharmony_ci 10162306a36Sopenharmony_ci if (engine > VPU_ENGINE_COPY) 10262306a36Sopenharmony_ci return -EINVAL; 10362306a36Sopenharmony_ci 10462306a36Sopenharmony_ci req.payload.engine_preempt.engine_idx = engine; 10562306a36Sopenharmony_ci req.payload.engine_preempt.preempt_id = preempt_id; 10662306a36Sopenharmony_ci 10762306a36Sopenharmony_ci ret = ivpu_ipc_send_receive(vdev, &req, VPU_JSM_MSG_ENGINE_PREEMPT_DONE, &resp, 10862306a36Sopenharmony_ci VPU_IPC_CHAN_ASYNC_CMD, vdev->timeout.jsm); 10962306a36Sopenharmony_ci if (ret) 11062306a36Sopenharmony_ci ivpu_err(vdev, "Failed to preempt engine %d: %d\n", engine, ret); 11162306a36Sopenharmony_ci 11262306a36Sopenharmony_ci return ret; 11362306a36Sopenharmony_ci} 11462306a36Sopenharmony_ci 11562306a36Sopenharmony_ciint ivpu_jsm_dyndbg_control(struct ivpu_device *vdev, char *command, size_t size) 11662306a36Sopenharmony_ci{ 11762306a36Sopenharmony_ci struct vpu_jsm_msg req = { .type = VPU_JSM_MSG_DYNDBG_CONTROL }; 11862306a36Sopenharmony_ci struct vpu_jsm_msg resp; 11962306a36Sopenharmony_ci int ret; 12062306a36Sopenharmony_ci 12162306a36Sopenharmony_ci strscpy(req.payload.dyndbg_control.dyndbg_cmd, command, VPU_DYNDBG_CMD_MAX_LEN); 12262306a36Sopenharmony_ci 12362306a36Sopenharmony_ci ret = ivpu_ipc_send_receive(vdev, &req, VPU_JSM_MSG_DYNDBG_CONTROL_RSP, &resp, 12462306a36Sopenharmony_ci VPU_IPC_CHAN_ASYNC_CMD, vdev->timeout.jsm); 12562306a36Sopenharmony_ci if (ret) 12662306a36Sopenharmony_ci ivpu_warn(vdev, "Failed to send command \"%s\": ret %d\n", command, ret); 12762306a36Sopenharmony_ci 12862306a36Sopenharmony_ci return ret; 12962306a36Sopenharmony_ci} 13062306a36Sopenharmony_ci 13162306a36Sopenharmony_ciint ivpu_jsm_trace_get_capability(struct ivpu_device *vdev, u32 *trace_destination_mask, 13262306a36Sopenharmony_ci u64 *trace_hw_component_mask) 13362306a36Sopenharmony_ci{ 13462306a36Sopenharmony_ci struct vpu_jsm_msg req = { .type = VPU_JSM_MSG_TRACE_GET_CAPABILITY }; 13562306a36Sopenharmony_ci struct vpu_jsm_msg resp; 13662306a36Sopenharmony_ci int ret; 13762306a36Sopenharmony_ci 13862306a36Sopenharmony_ci ret = ivpu_ipc_send_receive(vdev, &req, VPU_JSM_MSG_TRACE_GET_CAPABILITY_RSP, &resp, 13962306a36Sopenharmony_ci VPU_IPC_CHAN_ASYNC_CMD, vdev->timeout.jsm); 14062306a36Sopenharmony_ci if (ret) { 14162306a36Sopenharmony_ci ivpu_warn(vdev, "Failed to get trace capability: %d\n", ret); 14262306a36Sopenharmony_ci return ret; 14362306a36Sopenharmony_ci } 14462306a36Sopenharmony_ci 14562306a36Sopenharmony_ci *trace_destination_mask = resp.payload.trace_capability.trace_destination_mask; 14662306a36Sopenharmony_ci *trace_hw_component_mask = resp.payload.trace_capability.trace_hw_component_mask; 14762306a36Sopenharmony_ci 14862306a36Sopenharmony_ci return ret; 14962306a36Sopenharmony_ci} 15062306a36Sopenharmony_ci 15162306a36Sopenharmony_ciint ivpu_jsm_trace_set_config(struct ivpu_device *vdev, u32 trace_level, u32 trace_destination_mask, 15262306a36Sopenharmony_ci u64 trace_hw_component_mask) 15362306a36Sopenharmony_ci{ 15462306a36Sopenharmony_ci struct vpu_jsm_msg req = { .type = VPU_JSM_MSG_TRACE_SET_CONFIG }; 15562306a36Sopenharmony_ci struct vpu_jsm_msg resp; 15662306a36Sopenharmony_ci int ret; 15762306a36Sopenharmony_ci 15862306a36Sopenharmony_ci req.payload.trace_config.trace_level = trace_level; 15962306a36Sopenharmony_ci req.payload.trace_config.trace_destination_mask = trace_destination_mask; 16062306a36Sopenharmony_ci req.payload.trace_config.trace_hw_component_mask = trace_hw_component_mask; 16162306a36Sopenharmony_ci 16262306a36Sopenharmony_ci ret = ivpu_ipc_send_receive(vdev, &req, VPU_JSM_MSG_TRACE_SET_CONFIG_RSP, &resp, 16362306a36Sopenharmony_ci VPU_IPC_CHAN_ASYNC_CMD, vdev->timeout.jsm); 16462306a36Sopenharmony_ci if (ret) 16562306a36Sopenharmony_ci ivpu_warn(vdev, "Failed to set config: %d\n", ret); 16662306a36Sopenharmony_ci 16762306a36Sopenharmony_ci return ret; 16862306a36Sopenharmony_ci} 16962306a36Sopenharmony_ci 17062306a36Sopenharmony_ciint ivpu_jsm_context_release(struct ivpu_device *vdev, u32 host_ssid) 17162306a36Sopenharmony_ci{ 17262306a36Sopenharmony_ci struct vpu_jsm_msg req = { .type = VPU_JSM_MSG_SSID_RELEASE }; 17362306a36Sopenharmony_ci struct vpu_jsm_msg resp; 17462306a36Sopenharmony_ci 17562306a36Sopenharmony_ci req.payload.ssid_release.host_ssid = host_ssid; 17662306a36Sopenharmony_ci 17762306a36Sopenharmony_ci return ivpu_ipc_send_receive(vdev, &req, VPU_JSM_MSG_SSID_RELEASE_DONE, &resp, 17862306a36Sopenharmony_ci VPU_IPC_CHAN_ASYNC_CMD, vdev->timeout.jsm); 17962306a36Sopenharmony_ci} 180