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:
10
msm/Kbuild
10
msm/Kbuild
@@ -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
|
||||||
|
|
||||||
|
@@ -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"
|
||||||
|
@@ -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
|
||||||
|
@@ -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;
|
||||||
|
@@ -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 {
|
||||||
|
@@ -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;
|
||||||
};
|
};
|
||||||
|
|
@@ -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
160
msm/eva/vm/cvp_vm_msgq.c
Normal 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
72
msm/eva/vm/cvp_vm_msgq.h
Normal 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
|
8
msm/eva/vm/cvp_vm_resource.c
Normal file
8
msm/eva/vm/cvp_vm_resource.c
Normal 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;
|
17
msm/eva/vm/cvp_vm_resource.h
Normal file
17
msm/eva/vm/cvp_vm_resource.h
Normal 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
|
Reference in New Issue
Block a user