msm: eva: Add vm sub-driver
Add framework for future implementation. Change-Id: I2ba070e791320e56339c632120ffa821e57db113 Signed-off-by: George Shen <quic_sqiao@quicinc.com>
这个提交包含在:
10
msm/Kbuild
10
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
|
||||
|
||||
|
@@ -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"
|
||||
|
@@ -7,6 +7,7 @@
|
||||
#define _MSM_COMM_DEF_H_
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/gunyah/gh_rm_drv.h>
|
||||
|
||||
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
|
||||
|
@@ -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;
|
||||
|
@@ -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 {
|
||||
|
@@ -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 <linux/types.h>
|
||||
#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;
|
||||
};
|
||||
|
@@ -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,
|
||||
};
|
||||
|
160
msm/eva/vm/cvp_vm_msgq.c
普通文件
160
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 <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
普通文件
72
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 <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
|
8
msm/eva/vm/cvp_vm_resource.c
普通文件
8
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;
|
17
msm/eva/vm/cvp_vm_resource.h
普通文件
17
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 <linux/types.h>
|
||||
#include "cvp_comm_def.h"
|
||||
|
||||
struct cvp_vm_resource {
|
||||
int reserved;
|
||||
};
|
||||
|
||||
extern struct cvp_vm_resource cvp_vm_rm;
|
||||
#endif
|
在新工单中引用
屏蔽一个用户