msm: eva: Add vm sub-driver

Add framework for future implementation.

Change-Id: I2ba070e791320e56339c632120ffa821e57db113
Signed-off-by: George Shen <quic_sqiao@quicinc.com>
This commit is contained in:
George Shen
2022-04-08 15:26:07 -07:00
parent 81fb7564e7
commit b129cf0b8a
12 changed files with 280 additions and 13 deletions

View File

@@ -4,7 +4,7 @@ LINUXINCLUDE += -I$(EVA_ROOT)/include \
#srctree is /kernel_platform/common/ #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/ -I$(srctree)/drivers/media/platform/msm/synx/
# add flag to compile mmrm actual implementatio instead of stub version. # add flag to compile mmrm actual implementatio instead of stub version.
@@ -29,7 +29,7 @@ ccflags-y += -DCONFIG_EVA_KALAMA=1
endif endif
ifeq ($(CONFIG_EVA_LE), 1) ifeq ($(CONFIG_EVA_LE), 1)
ccflags-y += -DCONFIG_EVA_LE=1 ccflags-y += -DCONFIG_EVA_TVM=1
endif endif
msm-eva-objs := eva/cvp.o \ msm-eva-objs := eva/cvp.o \
@@ -38,7 +38,7 @@ msm-eva-objs := eva/cvp.o \
eva/msm_cvp_common.o \ eva/msm_cvp_common.o \
eva/msm_cvp_core.o \ eva/msm_cvp_core.o \
eva/msm_cvp.o \ eva/msm_cvp.o \
eva/msm_smem.o \ eva/cvp_smem.o \
eva/msm_cvp_debug.o \ eva/msm_cvp_debug.o \
eva/msm_cvp_res_parse.o \ eva/msm_cvp_res_parse.o \
eva/cvp_dump.o \ eva/cvp_dump.o \
@@ -51,6 +51,8 @@ msm-eva-objs := eva/cvp.o \
eva/msm_cvp_buf.o \ eva/msm_cvp_buf.o \
eva/msm_cvp_synx.o \ eva/msm_cvp_synx.o \
eva/cvp_fw_load.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 obj-m += msm-eva.o

View File

@@ -26,7 +26,7 @@
#include "msm_cvp_clocks.h" #include "msm_cvp_clocks.h"
#include "msm_cvp_dsp.h" #include "msm_cvp_dsp.h"
#include "msm_cvp.h" #include "msm_cvp.h"
#include "msm_cvp_vm.h" #include "vm/cvp_vm.h"
#define CLASS_NAME "cvp" #define CLASS_NAME "cvp"
#define DRIVER_NAME "cvp" #define DRIVER_NAME "cvp"

View File

@@ -7,6 +7,7 @@
#define _MSM_COMM_DEF_H_ #define _MSM_COMM_DEF_H_
#include <linux/types.h> #include <linux/types.h>
#include <linux/gunyah/gh_rm_drv.h>
enum op_mode { enum op_mode {
OP_NORMAL, OP_NORMAL,
@@ -23,7 +24,7 @@ enum queue_state {
QUEUE_INVALID, QUEUE_INVALID,
}; };
#ifdef CONFIG_EVA_LE #ifdef CONFIG_EVA_TVM
#else /* LA target starts here */ #else /* LA target starts here */
@@ -35,6 +36,6 @@ enum queue_state {
#define CVP_MINIDUMP_ENABLED 1 #define CVP_MINIDUMP_ENABLED 1
#endif #endif
#endif /* End CONFIG_EVA_LE */ #endif /* End CONFIG_EVA_TVM */
#endif #endif

View File

@@ -30,7 +30,7 @@
#include "cvp_hfi_io.h" #include "cvp_hfi_io.h"
#include "msm_cvp_dsp.h" #include "msm_cvp_dsp.h"
#include "msm_cvp_clocks.h" #include "msm_cvp_clocks.h"
#include "msm_cvp_vm.h" #include "vm/cvp_vm.h"
#include "cvp_dump.h" #include "cvp_dump.h"
#define REG_ADDR_OFFSET_BITMASK 0x000FFFFF #define REG_ADDR_OFFSET_BITMASK 0x000FFFFF
@@ -1397,7 +1397,7 @@ fail_dma_alloc:
static void __interface_queues_release(struct iris_hfi_device *device) static void __interface_queues_release(struct iris_hfi_device *device)
{ {
#ifdef CONFIG_EVA_LE #ifdef CONFIG_EVA_TVM
int i; int i;
struct cvp_hfi_mem_map_table *qdss; struct cvp_hfi_mem_map_table *qdss;
struct cvp_hfi_mem_map *mem_map; struct cvp_hfi_mem_map *mem_map;

View File

@@ -37,8 +37,9 @@ enum cvp_msg_prio {
CVP_FW = 0x001000, CVP_FW = 0x001000,
CVP_SESS = 0x002000, CVP_SESS = 0x002000,
CVP_HFI = 0x004000, CVP_HFI = 0x004000,
CVP_VM = 0x008000,
CVP_DBG = CVP_MEM | CVP_SYNX | CVP_CORE | CVP_REG | 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 { enum cvp_msg_out {

View File

@@ -3,14 +3,16 @@
* Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved.
*/ */
#ifndef _MSM_CVP_VM_H_ #ifndef _CVP_VM_H_
#define _MSM_CVP_VM_H_ #define _CVP_VM_H_
#include <linux/types.h> #include <linux/types.h>
#include "cvp_comm_def.h" #include "cvp_comm_def.h"
#include "msm_cvp_core.h" #include "msm_cvp_core.h"
#include "msm_cvp_internal.h" #include "msm_cvp_internal.h"
#include "cvp_core_hfi.h" #include "cvp_core_hfi.h"
#include "cvp_vm_msgq.h"
#include "cvp_vm_resource.h"
enum cvp_vm_id { enum cvp_vm_id {
VM_PRIMARY = 1, VM_PRIMARY = 1,
@@ -34,6 +36,8 @@ struct msm_cvp_vm_ops {
struct msm_cvp_vm_manager { struct msm_cvp_vm_manager {
enum cvp_vm_state vm_state; enum cvp_vm_state vm_state;
enum cvp_vm_id vm_id; 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; struct msm_cvp_vm_ops *vm_ops;
}; };

View File

@@ -30,7 +30,7 @@
#include "msm_cvp_dsp.h" #include "msm_cvp_dsp.h"
#include "msm_cvp_clocks.h" #include "msm_cvp_clocks.h"
#include "cvp_dump.h" #include "cvp_dump.h"
#include "msm_cvp_vm.h" #include "cvp_vm.h"
#define FIRMWARE_SIZE 0X00A00000 #define FIRMWARE_SIZE 0X00A00000
@@ -44,6 +44,8 @@ static struct msm_cvp_vm_ops vm_ops = {
}; };
struct msm_cvp_vm_manager vm_manager = { struct msm_cvp_vm_manager vm_manager = {
.msgq_drv = &cvp_ipc_msgq,
.vm_rm = &cvp_vm_rm,
.vm_ops = &vm_ops, .vm_ops = &vm_ops,
}; };

160
msm/eva/vm/cvp_vm_msgq.c Normal file
View File

@@ -0,0 +1,160 @@
/* SPDX-License-Identifier: GPL-2.0-only
*
* Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/kthread.h>
#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,
};

72
msm/eva/vm/cvp_vm_msgq.h Normal file
View File

@@ -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 <linux/types.h>
#include <linux/gunyah/gh_msgq.h>
#include <linux/gunyah/gh_rm_drv.h>
#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

View File

@@ -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;

View File

@@ -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 <linux/types.h>
#include "cvp_comm_def.h"
struct cvp_vm_resource {
int reserved;
};
extern struct cvp_vm_resource cvp_vm_rm;
#endif