diff --git a/msm/Kbuild b/msm/Kbuild index 658d2f0cb2..ad3949ec6d 100644 --- a/msm/Kbuild +++ b/msm/Kbuild @@ -4,7 +4,7 @@ LINUXINCLUDE += -I$(EVA_ROOT)/include \ #srctree is /kernel_platform/common/ -ccflags-y += -I$(srctree)/techpack/eva/msm/eva/ \ +ccflags-y += -I$(EVA_ROOT)/msm/eva/ \ -I$(srctree)/drivers/media/platform/msm/synx/ # add flag to compile mmrm actual implementatio instead of stub version. @@ -29,7 +29,7 @@ ccflags-y += -DCONFIG_EVA_KALAMA=1 endif ifeq ($(CONFIG_EVA_LE), 1) -ccflags-y += -DCONFIG_EVA_LE=1 +ccflags-y += -DCONFIG_EVA_TVM=1 endif msm-eva-objs := eva/cvp.o \ @@ -38,7 +38,7 @@ msm-eva-objs := eva/cvp.o \ eva/msm_cvp_common.o \ eva/msm_cvp_core.o \ eva/msm_cvp.o \ - eva/msm_smem.o \ + eva/cvp_smem.o \ eva/msm_cvp_debug.o \ eva/msm_cvp_res_parse.o \ eva/cvp_dump.o \ @@ -51,6 +51,8 @@ msm-eva-objs := eva/cvp.o \ eva/msm_cvp_buf.o \ eva/msm_cvp_synx.o \ eva/cvp_fw_load.o \ - eva/msm_cvp_vm.o + eva/vm/cvp_vm_main.o \ + eva/vm/cvp_vm_msgq.o \ + eva/vm/cvp_vm_resource.o obj-m += msm-eva.o diff --git a/msm/eva/cvp.c b/msm/eva/cvp.c index 43ca66e43b..b17e658bc8 100644 --- a/msm/eva/cvp.c +++ b/msm/eva/cvp.c @@ -26,7 +26,7 @@ #include "msm_cvp_clocks.h" #include "msm_cvp_dsp.h" #include "msm_cvp.h" -#include "msm_cvp_vm.h" +#include "vm/cvp_vm.h" #define CLASS_NAME "cvp" #define DRIVER_NAME "cvp" diff --git a/msm/eva/cvp_comm_def.h b/msm/eva/cvp_comm_def.h index 9ddd73cc5d..37e204c59c 100644 --- a/msm/eva/cvp_comm_def.h +++ b/msm/eva/cvp_comm_def.h @@ -7,6 +7,7 @@ #define _MSM_COMM_DEF_H_ #include +#include enum op_mode { OP_NORMAL, @@ -23,7 +24,7 @@ enum queue_state { QUEUE_INVALID, }; -#ifdef CONFIG_EVA_LE +#ifdef CONFIG_EVA_TVM #else /* LA target starts here */ @@ -35,6 +36,6 @@ enum queue_state { #define CVP_MINIDUMP_ENABLED 1 #endif -#endif /* End CONFIG_EVA_LE */ +#endif /* End CONFIG_EVA_TVM */ #endif diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index f5d107db56..1325d0910e 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -30,7 +30,7 @@ #include "cvp_hfi_io.h" #include "msm_cvp_dsp.h" #include "msm_cvp_clocks.h" -#include "msm_cvp_vm.h" +#include "vm/cvp_vm.h" #include "cvp_dump.h" #define REG_ADDR_OFFSET_BITMASK 0x000FFFFF @@ -1397,7 +1397,7 @@ fail_dma_alloc: static void __interface_queues_release(struct iris_hfi_device *device) { -#ifdef CONFIG_EVA_LE +#ifdef CONFIG_EVA_TVM int i; struct cvp_hfi_mem_map_table *qdss; struct cvp_hfi_mem_map *mem_map; diff --git a/msm/eva/msm_smem.c b/msm/eva/cvp_smem.c similarity index 100% rename from msm/eva/msm_smem.c rename to msm/eva/cvp_smem.c diff --git a/msm/eva/msm_cvp_debug.h b/msm/eva/msm_cvp_debug.h index 838fa33fa5..08f195ba43 100644 --- a/msm/eva/msm_cvp_debug.h +++ b/msm/eva/msm_cvp_debug.h @@ -37,8 +37,9 @@ enum cvp_msg_prio { CVP_FW = 0x001000, CVP_SESS = 0x002000, CVP_HFI = 0x004000, + CVP_VM = 0x008000, CVP_DBG = CVP_MEM | CVP_SYNX | CVP_CORE | CVP_REG | - CVP_PWR | CVP_DSP | CVP_SESS | CVP_HFI | CVP_PKT, + CVP_PWR | CVP_DSP | CVP_SESS | CVP_HFI | CVP_PKT | CVP_VM, }; enum cvp_msg_out { diff --git a/msm/eva/msm_cvp_vm.h b/msm/eva/vm/cvp_vm.h similarity index 83% rename from msm/eva/msm_cvp_vm.h rename to msm/eva/vm/cvp_vm.h index 19450e7c9a..80967982ec 100644 --- a/msm/eva/msm_cvp_vm.h +++ b/msm/eva/vm/cvp_vm.h @@ -3,14 +3,16 @@ * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved. */ -#ifndef _MSM_CVP_VM_H_ -#define _MSM_CVP_VM_H_ +#ifndef _CVP_VM_H_ +#define _CVP_VM_H_ #include #include "cvp_comm_def.h" #include "msm_cvp_core.h" #include "msm_cvp_internal.h" #include "cvp_core_hfi.h" +#include "cvp_vm_msgq.h" +#include "cvp_vm_resource.h" enum cvp_vm_id { VM_PRIMARY = 1, @@ -34,6 +36,8 @@ struct msm_cvp_vm_ops { struct msm_cvp_vm_manager { enum cvp_vm_state vm_state; enum cvp_vm_id vm_id; + struct cvp_msgq_drv *msgq_drv; + struct cvp_vm_resource *vm_rm; struct msm_cvp_vm_ops *vm_ops; }; diff --git a/msm/eva/msm_cvp_vm.c b/msm/eva/vm/cvp_vm_main.c similarity index 98% rename from msm/eva/msm_cvp_vm.c rename to msm/eva/vm/cvp_vm_main.c index 61aae613e5..61f98529fa 100644 --- a/msm/eva/msm_cvp_vm.c +++ b/msm/eva/vm/cvp_vm_main.c @@ -30,7 +30,7 @@ #include "msm_cvp_dsp.h" #include "msm_cvp_clocks.h" #include "cvp_dump.h" -#include "msm_cvp_vm.h" +#include "cvp_vm.h" #define FIRMWARE_SIZE 0X00A00000 @@ -44,6 +44,8 @@ static struct msm_cvp_vm_ops vm_ops = { }; struct msm_cvp_vm_manager vm_manager = { + .msgq_drv = &cvp_ipc_msgq, + .vm_rm = &cvp_vm_rm, .vm_ops = &vm_ops, }; diff --git a/msm/eva/vm/cvp_vm_msgq.c b/msm/eva/vm/cvp_vm_msgq.c new file mode 100644 index 0000000000..bad20e06a7 --- /dev/null +++ b/msm/eva/vm/cvp_vm_msgq.c @@ -0,0 +1,160 @@ +/* SPDX-License-Identifier: GPL-2.0-only + * + * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#include +#include "cvp_vm_msgq.h" +#include "msm_cvp_debug.h" + +/** + * cvp_msgq_receiver - thread function that receive msg from gunyah msgq + * data: cvp_msgq_drv pointer + * + * Note: single thread. If the sub-function or global data used in this + * function is also used somehwere else, please add rx_lock. + */ +static int cvp_msgq_receiver(void *data) +{ + struct cvp_msgq_drv *msgq_drv = data; + + if (IS_ERR_OR_NULL(msgq_drv)) + return -EINVAL; + + return 0; +} + +static int cvp_complete_msgq_init(struct cvp_msgq_drv *msgq_drv) +{ + int i; + + msgq_drv->receiver_thread = kthread_run( + cvp_msgq_receiver, + (void *)msgq_drv, + "CVP msgq receiver"); + if (IS_ERR_OR_NULL(msgq_drv->receiver_thread)) { + dprintk(CVP_ERR, "Failed to start msgq receiver thread\n"); + return -EINVAL; + } + + mutex_init(&msgq_drv->ipc_lock); + + for (i = 0; i <= CVP_MAX_IPC_CMD; i++) + init_completion(&msgq_drv->completions[i]); + + return 0; +} + +static int cvp_msgq_cb(struct notifier_block *nb, + unsigned long cmd, void *data) +{ + struct gh_rm_notif_vm_status_payload *vm_status_payload; + struct cvp_gh_msgq_config *msgq_config; + struct cvp_msgq_drv *msgq_drv; + gh_vmid_t peer_vmid; + gh_vmid_t self_vmid; + int rc; + + + if (IS_ERR_OR_NULL(nb)) + return -EINVAL; + + msgq_config = container_of(nb, struct cvp_gh_msgq_config, rm_nb); + msgq_drv = container_of(msgq_config, struct cvp_msgq_drv, config); + + if (cmd != GH_RM_NOTIF_VM_STATUS) + return NOTIFY_DONE; + + /** + * Check VM status, only GH_TRUSTED_VM notification activate + * Gunyah msgq registration + */ + vm_status_payload = (struct gh_rm_notif_vm_status_payload *)data; + + if (vm_status_payload->vm_status != GH_RM_VM_STATUS_READY) + return -12; + + if (gh_rm_get_vmid(msgq_config->peer_id, &peer_vmid)) + return -13; + + if (gh_rm_get_vmid(GH_PRIMARY_VM, &self_vmid)) + return -14; + + if (peer_vmid != vm_status_payload->vmid) + return NOTIFY_DONE; + + dprintk(CVP_VM, "%s vmid=%d, peer_vmid=%d\n", vm_status_payload->vmid, + peer_vmid); + + if (msgq_config->handle) + return -15; + + msgq_config->handle = gh_msgq_register(GH_MSGQ_LABEL_EVA); + if (IS_ERR(msgq_config->handle)) { + rc = PTR_ERR(msgq_drv->config.handle); + dprintk(CVP_ERR, "PVM failed to register msgq %d\n", rc); + return rc; + } + + rc = cvp_complete_msgq_init(msgq_drv); + + return rc; +} + +static int cvp_msgq_init(struct cvp_msgq_drv *msgq_drv) +{ + int rc = 0; + + msgq_drv->config.label = GH_MSGQ_LABEL_EVA; + msgq_drv->config.handle = NULL; +#ifndef CONFIG_EVA_TVM + /* PVM init */ + msgq_drv->config.peer_id = GH_TRUSTED_VM; + msgq_drv->config.rm_nb.notifier_call = cvp_msgq_cb; + rc = gh_rm_register_notifier(&msgq_drv->config.rm_nb); + if (rc) { + dprintk(CVP_ERR, "PVM Fail register msgq notifier %d\n", rc); + return rc; + } +#else + /* TVM init */ + msgq_drv->config.handle = gh_msgq_register(GH_MSGQ_LABEL_EVA); + if (IS_ERR(msgq_drv->config.handle)) { + rc = PTR_ERR(msgq_drv->config.handle); + dprintk(CVP_ERR, "TVM failed to register msgq %d\n", rc); + return rc; + } + rc = cvp_msgq_complete_init(msgq_drv); +#endif + return rc; +} + +static int cvp_msgq_deinit(struct cvp_msgq_drv *msgq_drv) +{ + if (msgq_drv->receiver_thread) + kthread_stop(msgq_drv->receiver_thread); + + return 0; +} + +static int cvp_msgq_send(struct cvp_msgq_drv *msgq_drv, + void *msg, size_t msg_size) +{ + return 0; +} + +static int cvp_msgq_receive(struct cvp_msgq_drv *msgq_drv) +{ + return 0; +} + +static struct cvp_msgq_ops msgq_ops = { + .msgq_init = cvp_msgq_init, + .msgq_deinit = cvp_msgq_deinit, + .msgq_send = cvp_msgq_send, + .msgq_receive = cvp_msgq_receive, +}; + +struct cvp_msgq_drv cvp_ipc_msgq = { + .ops = &msgq_ops, +}; diff --git a/msm/eva/vm/cvp_vm_msgq.h b/msm/eva/vm/cvp_vm_msgq.h new file mode 100644 index 0000000000..91ef3dde98 --- /dev/null +++ b/msm/eva/vm/cvp_vm_msgq.h @@ -0,0 +1,72 @@ +/* SPDX-License-Identifier: GPL-2.0-only + * + * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#ifndef _CVP_VM_MSGQ_H_ +#define _CVP_VM_MSGQ_H_ + +#include +#include +#include +#include "cvp_comm_def.h" + +#define MAX_CVP_IPC_LEN 16 + +enum CVP_IPC_MSG_TYPE { + REQUEST_SESS_CTRL = 0, + RELEASE_SESS_CTRL = 1, + REQUEST_EVA_RESET = 2, + RECLAIM_SESS_CTRL = 3, /* Only PVM can reclaim sesession control */ + CVP_MAX_IPC_CMD = 4, +}; + +struct cvp_ipc_msg { + /* type format: + * bit 31: 0->PVM initiated; 1->TVM initiated + * bit 2~0: CVP_IPC_MSG_TYPE + */ + uint32_t type; + uint32_t ver; + uint32_t len; + uint32_t resv; + uint32_t data[MAX_CVP_IPC_LEN]; +}; + +struct cvp_gh_msgq_config { + int peer_id; + int label; + void *handle; + struct notifier_block rm_nb; +}; + +struct cvp_msgq_ops; + +struct cvp_msgq_drv { + struct mutex ipc_lock; /* Mutex for sending MSG */ + struct cvp_gh_msgq_config config; + struct task_struct *receiver_thread; + struct completion completions[CVP_MAX_IPC_CMD + 1]; + /* + * pending_local_cmd: the command is being processed locally. + * The command is a request sent from remote VM + */ + struct cvp_ipc_msg pending_local_cmd; + /* + * pending_remote_rsp: the command is being processing remotely. + * The command is a request sent by local VM + */ + struct cvp_ipc_msg pending_remote_rsp; + struct cvp_msgq_ops *ops; +}; + +struct cvp_msgq_ops { + int (*msgq_init)(struct cvp_msgq_drv *msgq_drv); + int (*msgq_send)(struct cvp_msgq_drv *msgq_drv, void *msg, + size_t msg_size); + int (*msgq_receive)(struct cvp_msgq_drv *msgq_drv); + int (*msgq_deinit)(struct cvp_msgq_drv *msgq_drv); +}; + +extern struct cvp_msgq_drv cvp_ipc_msgq; +#endif diff --git a/msm/eva/vm/cvp_vm_resource.c b/msm/eva/vm/cvp_vm_resource.c new file mode 100644 index 0000000000..df382c3171 --- /dev/null +++ b/msm/eva/vm/cvp_vm_resource.c @@ -0,0 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-only + * + * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#include "cvp_vm_resource.h" + +struct cvp_vm_resource cvp_vm_rm; diff --git a/msm/eva/vm/cvp_vm_resource.h b/msm/eva/vm/cvp_vm_resource.h new file mode 100644 index 0000000000..92fb33613b --- /dev/null +++ b/msm/eva/vm/cvp_vm_resource.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: GPL-2.0-only + * + * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#ifndef _CVP_VM_RESOURCE_H_ +#define _CVP_VM_RESOURCE_H_ + +#include +#include "cvp_comm_def.h" + +struct cvp_vm_resource { + int reserved; +}; + +extern struct cvp_vm_resource cvp_vm_rm; +#endif