mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-09 05:39:54 -04:00
Merge "msm: cvp: CVP DSP driver restructure for Lahaina"
This commit is contained in:
commit
3db6466154
6 changed files with 390 additions and 568 deletions
|
|
@ -1,6 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/debugfs.h>
|
||||
|
|
@ -26,7 +26,6 @@
|
|||
#include "msm_cvp_clocks.h"
|
||||
#include "msm_cvp_dsp.h"
|
||||
|
||||
#define BASE_DEVICE_NUMBER 32
|
||||
#define CLASS_NAME "cvp"
|
||||
#define DRIVER_NAME "cvp"
|
||||
|
||||
|
|
@ -34,18 +33,15 @@ struct msm_cvp_drv *cvp_driver;
|
|||
|
||||
static int cvp_open(struct inode *inode, struct file *filp)
|
||||
{
|
||||
int rc;
|
||||
struct msm_cvp_core *core = container_of(inode->i_cdev,
|
||||
struct msm_cvp_core, cdev);
|
||||
struct msm_cvp_inst *inst;
|
||||
|
||||
dprintk(CVP_DBG, "%s: Enter\n", __func__);
|
||||
|
||||
rc = cvp_dsp_device_init();
|
||||
inst = msm_cvp_open(core->id, MSM_CVP_USER);
|
||||
if (!inst || rc) {
|
||||
dprintk(CVP_ERR,
|
||||
"Failed to create cvp instance rc=%d\n", rc);
|
||||
if (!inst) {
|
||||
dprintk(CVP_ERR, "Failed to create cvp instance\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
filp->private_data = inst;
|
||||
|
|
@ -551,8 +547,7 @@ static int __init msm_cvp_init(void)
|
|||
{
|
||||
int rc = 0;
|
||||
|
||||
cvp_driver = kzalloc(sizeof(*cvp_driver),
|
||||
GFP_KERNEL);
|
||||
cvp_driver = kzalloc(sizeof(*cvp_driver), GFP_KERNEL);
|
||||
if (!cvp_driver) {
|
||||
dprintk(CVP_ERR,
|
||||
"Failed to allocate memroy for msm_cvp_drv\n");
|
||||
|
|
@ -582,6 +577,10 @@ static int __init msm_cvp_init(void)
|
|||
cvp_driver->frame_buf_cache = KMEM_CACHE(msm_cvp_frame_buf, 0);
|
||||
cvp_driver->internal_buf_cache = KMEM_CACHE(msm_cvp_internal_buffer, 0);
|
||||
|
||||
rc = cvp_dsp_device_init();
|
||||
if (rc)
|
||||
dprintk(CVP_WARN, "Failed to initialize DSP driver\n");
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef __H_CVP_CORE_HFI_H__
|
||||
|
|
@ -201,11 +201,6 @@ struct iris_resources {
|
|||
struct msm_cvp_fw fw;
|
||||
};
|
||||
|
||||
enum dsp_flag {
|
||||
DSP_INIT = BIT(0),
|
||||
DSP_SUSPEND = BIT(1),
|
||||
};
|
||||
|
||||
enum iris_hfi_state {
|
||||
IRIS_STATE_DEINIT = 1,
|
||||
IRIS_STATE_INIT,
|
||||
|
|
@ -229,7 +224,6 @@ struct iris_hfi_vpu_ops {
|
|||
};
|
||||
|
||||
struct iris_hfi_device {
|
||||
struct list_head list;
|
||||
struct list_head sess_head;
|
||||
u32 version;
|
||||
u32 intr_status;
|
||||
|
|
@ -250,7 +244,6 @@ struct iris_hfi_device {
|
|||
struct cvp_mem_addr mem_addr;
|
||||
struct cvp_iface_q_info iface_queues[CVP_IFACEQ_NUMQ];
|
||||
struct cvp_iface_q_info dsp_iface_queues[CVP_IFACEQ_NUMQ];
|
||||
u32 dsp_flags;
|
||||
struct cvp_hal_data *cvp_hal_data;
|
||||
struct workqueue_struct *cvp_workq;
|
||||
struct workqueue_struct *iris_pm_workq;
|
||||
|
|
@ -267,7 +260,6 @@ struct iris_hfi_device {
|
|||
unsigned int skip_pc_count;
|
||||
struct msm_cvp_capability *sys_init_capabilities;
|
||||
struct iris_hfi_vpu_ops *vpu_ops;
|
||||
struct delayed_work dsp_init_work;
|
||||
};
|
||||
|
||||
void cvp_iris_hfi_delete_device(void *device);
|
||||
|
|
|
|||
|
|
@ -264,7 +264,6 @@ const int cvp_max_packets = 32;
|
|||
|
||||
static void iris_hfi_pm_handler(struct work_struct *work);
|
||||
static DECLARE_DELAYED_WORK(iris_hfi_pm_work, iris_hfi_pm_handler);
|
||||
static void dsp_init_work_handler(struct work_struct *work);
|
||||
static inline int __resume(struct iris_hfi_device *device);
|
||||
static inline int __suspend(struct iris_hfi_device *device);
|
||||
static int __disable_regulators(struct iris_hfi_device *device);
|
||||
|
|
@ -420,41 +419,6 @@ static void __dump_packet(u8 *packet, enum cvp_msg_prio log_level)
|
|||
}
|
||||
}
|
||||
|
||||
static int __dsp_send_hfi_queue(struct iris_hfi_device *device)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if (msm_cvp_dsp_disable) {
|
||||
dprintk(CVP_WARN, "%s: DSP support is disabled\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!device->dsp_iface_q_table.mem_data.dma_handle) {
|
||||
dprintk(CVP_ERR, "%s: invalid dsm_handle\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (device->dsp_flags & DSP_INIT) {
|
||||
dprintk(CVP_DBG, "%s: dsp already inited\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
dprintk(CVP_DBG, "%s: hfi queue %#llx size %d\n",
|
||||
__func__, device->dsp_iface_q_table.mem_data.dma_handle,
|
||||
device->dsp_iface_q_table.mem_data.size);
|
||||
rc = cvp_dsp_send_cmd_hfi_queue(
|
||||
(phys_addr_t *)device->dsp_iface_q_table.mem_data.dma_handle,
|
||||
device->dsp_iface_q_table.mem_data.size, device);
|
||||
if (rc) {
|
||||
dprintk(CVP_ERR, "%s: dsp hfi queue init failed\n", __func__);
|
||||
return rc;
|
||||
}
|
||||
|
||||
device->dsp_flags |= DSP_INIT;
|
||||
dprintk(CVP_DBG, "%s: dsp inited\n", __func__);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int __dsp_suspend(struct iris_hfi_device *device, bool force, u32 flags)
|
||||
{
|
||||
int rc;
|
||||
|
|
@ -463,12 +427,6 @@ static int __dsp_suspend(struct iris_hfi_device *device, bool force, u32 flags)
|
|||
if (msm_cvp_dsp_disable)
|
||||
return 0;
|
||||
|
||||
if (!(device->dsp_flags & DSP_INIT))
|
||||
return 0;
|
||||
|
||||
if (device->dsp_flags & DSP_SUSPEND)
|
||||
return 0;
|
||||
|
||||
list_for_each_entry(temp, &device->sess_head, list) {
|
||||
/* if forceful suspend, don't check session pause info */
|
||||
if (force)
|
||||
|
|
@ -491,7 +449,6 @@ static int __dsp_suspend(struct iris_hfi_device *device, bool force, u32 flags)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
device->dsp_flags |= DSP_SUSPEND;
|
||||
dprintk(CVP_DBG, "%s: dsp suspended\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -503,11 +460,6 @@ static int __dsp_resume(struct iris_hfi_device *device, u32 flags)
|
|||
if (msm_cvp_dsp_disable)
|
||||
return 0;
|
||||
|
||||
if (!(device->dsp_flags & DSP_SUSPEND)) {
|
||||
dprintk(CVP_DBG, "%s: dsp not suspended\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
dprintk(CVP_DBG, "%s: resume dsp\n", __func__);
|
||||
rc = cvp_dsp_resume(flags);
|
||||
if (rc) {
|
||||
|
|
@ -517,7 +469,6 @@ static int __dsp_resume(struct iris_hfi_device *device, u32 flags)
|
|||
return rc;
|
||||
}
|
||||
|
||||
device->dsp_flags &= ~DSP_SUSPEND;
|
||||
dprintk(CVP_DBG, "%s: dsp resumed\n", __func__);
|
||||
return rc;
|
||||
}
|
||||
|
|
@ -529,13 +480,6 @@ static int __dsp_shutdown(struct iris_hfi_device *device, u32 flags)
|
|||
if (msm_cvp_dsp_disable)
|
||||
return 0;
|
||||
|
||||
cvp_dsp_set_cvp_ssr();
|
||||
|
||||
if (!(device->dsp_flags & DSP_INIT)) {
|
||||
dprintk(CVP_WARN, "%s: dsp not inited\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
dprintk(CVP_DBG, "%s: shutdown dsp\n", __func__);
|
||||
rc = cvp_dsp_shutdown(flags);
|
||||
if (rc) {
|
||||
|
|
@ -545,7 +489,6 @@ static int __dsp_shutdown(struct iris_hfi_device *device, u32 flags)
|
|||
WARN_ON(1);
|
||||
}
|
||||
|
||||
device->dsp_flags &= ~DSP_INIT;
|
||||
dprintk(CVP_DBG, "%s: dsp shutdown successful\n", __func__);
|
||||
return rc;
|
||||
}
|
||||
|
|
@ -1992,43 +1935,6 @@ static int __sys_set_power_control(struct iris_hfi_device *device,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void dsp_init_work_handler(struct work_struct *work)
|
||||
{
|
||||
int rc = 0;
|
||||
static int retry_count;
|
||||
struct iris_hfi_device *device;
|
||||
|
||||
if (!work) {
|
||||
dprintk(CVP_ERR, "%s: NULL device\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
device = container_of(work, struct iris_hfi_device, dsp_init_work.work);
|
||||
if (!device) {
|
||||
dprintk(CVP_ERR, "%s: NULL device\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
dprintk(CVP_PROF, "Entering %s\n", __func__);
|
||||
|
||||
mutex_lock(&device->lock);
|
||||
rc = __dsp_send_hfi_queue(device);
|
||||
mutex_unlock(&device->lock);
|
||||
|
||||
if (rc) {
|
||||
if (retry_count > MAX_DSP_INIT_ATTEMPTS) {
|
||||
dprintk(CVP_ERR, "%s: max trials exceeded\n", __func__);
|
||||
return;
|
||||
}
|
||||
dprintk(CVP_PROF, "%s: Attempt to init DSP %d\n",
|
||||
__func__, retry_count);
|
||||
|
||||
schedule_delayed_work(&device->dsp_init_work,
|
||||
msecs_to_jiffies(CVP_MAX_WAIT_TIME));
|
||||
++retry_count;
|
||||
}
|
||||
}
|
||||
|
||||
static int iris_hfi_core_init(void *device)
|
||||
{
|
||||
int rc = 0;
|
||||
|
|
@ -2115,13 +2021,12 @@ static int iris_hfi_core_init(void *device)
|
|||
pm_qos_add_request(&dev->qos, PM_QOS_CPU_DMA_LATENCY,
|
||||
dev->res->pm_qos_latency_us);
|
||||
|
||||
rc = __dsp_send_hfi_queue(device);
|
||||
if (rc)
|
||||
schedule_delayed_work(&dev->dsp_init_work,
|
||||
msecs_to_jiffies(CVP_MAX_WAIT_TIME));
|
||||
mutex_unlock(&dev->lock);
|
||||
|
||||
cvp_dsp_send_hfi_queue();
|
||||
|
||||
dprintk(CVP_DBG, "Core inited successfully\n");
|
||||
mutex_unlock(&dev->lock);
|
||||
|
||||
return 0;
|
||||
err_core_init:
|
||||
__set_state(dev, IRIS_STATE_DEINIT);
|
||||
|
|
@ -4574,8 +4479,6 @@ static struct iris_hfi_device *__add_device(u32 device_id,
|
|||
mutex_init(&hdevice->lock);
|
||||
INIT_LIST_HEAD(&hdevice->sess_head);
|
||||
|
||||
INIT_DELAYED_WORK(&hdevice->dsp_init_work, dsp_init_work_handler);
|
||||
|
||||
return hdevice;
|
||||
|
||||
err_cleanup:
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
#include <linux/module.h>
|
||||
#include <linux/rpmsg.h>
|
||||
|
|
@ -8,405 +8,284 @@
|
|||
#include <linux/of_fdt.h>
|
||||
#include <soc/qcom/secure_buffer.h>
|
||||
#include "msm_cvp_dsp.h"
|
||||
|
||||
#define VMID_CDSP_Q6 (30)
|
||||
#define SRC_VM_NUM 1
|
||||
#define DEST_VM_NUM 2
|
||||
#define CVP_DSP_SEND_HFI_CMD_QUEUE 0
|
||||
#define CVP_DSP_SUSPEND 1
|
||||
#define CVP_DSP_RESUME 2
|
||||
#define CVP_DSP_SHUTDOWN 3
|
||||
#define CVP_DSP_REGISTER_BUFFER 4
|
||||
#define CVP_DSP_DEREGISTER_BUFFER 5
|
||||
#define STATUS_INIT 0
|
||||
#define STATUS_DEINIT 1
|
||||
#define STATUS_OK 2
|
||||
#define STATUS_SSR 3
|
||||
#define CVP_DSP_MAX_RESERVED 5
|
||||
|
||||
struct cvp_dsp_cmd_msg {
|
||||
uint32_t cmd_msg_type;
|
||||
int32_t ret_val;
|
||||
uint64_t msg_ptr;
|
||||
uint32_t msg_ptr_len;
|
||||
uint32_t buff_fd_iova;
|
||||
uint32_t buff_index;
|
||||
uint32_t buff_size;
|
||||
uint32_t session_id;
|
||||
int32_t ddr_type;
|
||||
uint32_t buff_fd;
|
||||
uint32_t buff_offset;
|
||||
uint32_t buff_fd_size;
|
||||
uint32_t reserved1;
|
||||
uint32_t reserved2;
|
||||
};
|
||||
|
||||
struct cvp_dsp_rsp_msg {
|
||||
uint32_t cmd_msg_type;
|
||||
int32_t ret_val;
|
||||
uint32_t reserved[CVP_DSP_MAX_RESERVED];
|
||||
};
|
||||
|
||||
struct cvp_dsp_rsp_context {
|
||||
struct completion work;
|
||||
};
|
||||
#include "msm_cvp_internal.h"
|
||||
|
||||
struct cvp_dsp_apps {
|
||||
struct mutex lock;
|
||||
struct rpmsg_device *chan;
|
||||
struct mutex smd_mutex;
|
||||
struct mutex reg_buffer_mutex;
|
||||
struct mutex dereg_buffer_mutex;
|
||||
int rpmsg_register;
|
||||
uint32_t cdsp_state;
|
||||
uint32_t cvp_shutdown;
|
||||
struct completion reg_buffer_work;
|
||||
struct completion dereg_buffer_work;
|
||||
struct completion shutdown_work;
|
||||
struct completion cmdqueue_send_work;
|
||||
struct work_struct ssr_work;
|
||||
struct iris_hfi_device *device;
|
||||
uint32_t state;
|
||||
bool hyp_assigned;
|
||||
uint64_t addr;
|
||||
uint32_t size;
|
||||
struct completion completions[CVP_DSP_MAX_CMD];
|
||||
};
|
||||
|
||||
|
||||
static struct cvp_dsp_apps gfa_cv;
|
||||
static int hlosVM[HLOS_VM_NUM] = {VMID_HLOS};
|
||||
static int dspVM[DSP_VM_NUM] = {VMID_HLOS, VMID_CDSP_Q6};
|
||||
static int dspVMperm[DSP_VM_NUM] = { PERM_READ | PERM_WRITE | PERM_EXEC,
|
||||
PERM_READ | PERM_WRITE | PERM_EXEC };
|
||||
static int hlosVMperm[HLOS_VM_NUM] = { PERM_READ | PERM_WRITE | PERM_EXEC };
|
||||
|
||||
static struct cvp_dsp_cmd_msg cmd_msg;
|
||||
|
||||
static struct cvp_dsp_rsp_msg cmd_msg_rsp;
|
||||
|
||||
static int cvp_dsp_send_cmd(void *msg, uint32_t len)
|
||||
static int cvp_dsp_send_cmd(struct cvp_dsp_cmd_msg *cmd, uint32_t len)
|
||||
{
|
||||
int rc = 0;
|
||||
struct cvp_dsp_apps *me = &gfa_cv;
|
||||
int err = 0;
|
||||
|
||||
dprintk(CVP_DBG, "%s: cmd = %d\n", __func__, cmd->type);
|
||||
|
||||
if (IS_ERR_OR_NULL(me->chan)) {
|
||||
dprintk(CVP_ERR, "%s: DSP GLink is not ready\n", __func__);
|
||||
err = -EINVAL;
|
||||
goto bail;
|
||||
rc = -EINVAL;
|
||||
goto exit;
|
||||
}
|
||||
rc = rpmsg_send(me->chan->ept, cmd, len);
|
||||
if (rc) {
|
||||
dprintk(CVP_ERR, "%s: DSP rpmsg_send failed rc=%d\n",
|
||||
__func__, rc);
|
||||
goto exit;
|
||||
}
|
||||
err = rpmsg_send(me->chan->ept, msg, len);
|
||||
|
||||
bail:
|
||||
return err;
|
||||
exit:
|
||||
return rc;
|
||||
}
|
||||
|
||||
void msm_cvp_cdsp_ssr_handler(struct work_struct *work)
|
||||
static int cvp_dsp_send_cmd_sync(struct cvp_dsp_cmd_msg *cmd, uint32_t len)
|
||||
{
|
||||
struct cvp_dsp_apps *me;
|
||||
uint64_t msg_ptr;
|
||||
uint32_t msg_ptr_len;
|
||||
int err;
|
||||
int rc = 0;
|
||||
struct cvp_dsp_apps *me = &gfa_cv;
|
||||
|
||||
me = container_of(work, struct cvp_dsp_apps, ssr_work);
|
||||
if (!me) {
|
||||
dprintk(CVP_ERR, "%s: Invalid params\n", __func__);
|
||||
return;
|
||||
dprintk(CVP_DBG, "%s: cmd = %d\n", __func__, cmd->type);
|
||||
|
||||
rc = cvp_dsp_send_cmd(cmd, len);
|
||||
if (rc) {
|
||||
dprintk(CVP_ERR, "%s: cvp_dsp_send_cmd failed rc=%d\n",
|
||||
__func__, rc);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
msg_ptr = cmd_msg.msg_ptr;
|
||||
msg_ptr_len = cmd_msg.msg_ptr_len;
|
||||
if (!wait_for_completion_timeout(&me->completions[cmd->type],
|
||||
msecs_to_jiffies(CVP_DSP_RESPONSE_TIMEOUT))) {
|
||||
dprintk(CVP_ERR, "%s cmd %d timeout\n", __func__, cmd->type);
|
||||
rc = -ETIMEDOUT;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
err = cvp_dsp_send_cmd_hfi_queue((phys_addr_t *)msg_ptr,
|
||||
msg_ptr_len,
|
||||
(void *)NULL);
|
||||
if (err) {
|
||||
exit:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int cvp_dsp_send_cmd_hfi_queue(phys_addr_t *phys_addr,
|
||||
uint32_t size_in_bytes)
|
||||
{
|
||||
int rc = 0;
|
||||
struct cvp_dsp_cmd_msg cmd;
|
||||
|
||||
cmd.type = CVP_DSP_SEND_HFI_QUEUE;
|
||||
cmd.msg_ptr = (uint64_t)phys_addr;
|
||||
cmd.msg_ptr_len = size_in_bytes;
|
||||
cmd.ddr_type = of_fdt_get_ddrtype();
|
||||
if (cmd.ddr_type < 0) {
|
||||
dprintk(CVP_ERR,
|
||||
"%s: Failed to send HFI Queue address. err=%d\n",
|
||||
__func__, err);
|
||||
return;
|
||||
"%s: Incorrect DDR type value %d\n",
|
||||
__func__, cmd.ddr_type);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (me->device) {
|
||||
mutex_lock(&me->device->lock);
|
||||
me->device->dsp_flags |= DSP_INIT;
|
||||
mutex_unlock(&me->device->lock);
|
||||
dprintk(CVP_DBG,
|
||||
"%s: address of buffer, PA=0x%pK size_buff=%d ddr_type=%d\n",
|
||||
__func__, phys_addr, size_in_bytes, cmd.ddr_type);
|
||||
|
||||
rc = cvp_dsp_send_cmd_sync(&cmd, sizeof(struct cvp_dsp_cmd_msg));
|
||||
if (rc) {
|
||||
dprintk(CVP_ERR,
|
||||
"%s: cvp_dsp_send_cmd failed rc = %d\n",
|
||||
__func__, rc);
|
||||
goto exit;
|
||||
}
|
||||
dprintk(CVP_DBG, "%s: dsp recover from SSR successfully\n", __func__);
|
||||
exit:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int cvp_hyp_assign_to_dsp(uint64_t addr, uint32_t size)
|
||||
{
|
||||
int rc = 0;
|
||||
struct cvp_dsp_apps *me = &gfa_cv;
|
||||
|
||||
if (!me->hyp_assigned) {
|
||||
rc = hyp_assign_phys(addr, size, hlosVM, HLOS_VM_NUM, dspVM,
|
||||
dspVMperm, DSP_VM_NUM);
|
||||
if (rc) {
|
||||
dprintk(CVP_ERR, "%s failed. rc=%d\n", __func__, rc);
|
||||
return rc;
|
||||
}
|
||||
me->addr = addr;
|
||||
me->size = size;
|
||||
me->hyp_assigned = true;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int cvp_hyp_assign_from_dsp(void)
|
||||
{
|
||||
int rc = 0;
|
||||
struct cvp_dsp_apps *me = &gfa_cv;
|
||||
|
||||
if (me->hyp_assigned) {
|
||||
rc = hyp_assign_phys(me->addr, me->size, dspVM, DSP_VM_NUM,
|
||||
hlosVM, hlosVMperm, HLOS_VM_NUM);
|
||||
if (rc) {
|
||||
dprintk(CVP_ERR, "%s failed. rc=%d\n", __func__, rc);
|
||||
return rc;
|
||||
}
|
||||
me->addr = 0;
|
||||
me->size = 0;
|
||||
me->hyp_assigned = false;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int cvp_dsp_rpmsg_probe(struct rpmsg_device *rpdev)
|
||||
{
|
||||
int err = 0;
|
||||
struct cvp_dsp_apps *me = &gfa_cv;
|
||||
uint32_t cdsp_state, cvp_shutdown;
|
||||
uint64_t msg_ptr;
|
||||
uint32_t msg_ptr_len;
|
||||
int srcVM[DEST_VM_NUM] = {VMID_HLOS, VMID_CDSP_Q6};
|
||||
int destVM[SRC_VM_NUM] = {VMID_HLOS};
|
||||
int destVMperm[SRC_VM_NUM] = { PERM_READ | PERM_WRITE | PERM_EXEC };
|
||||
|
||||
if (strcmp(rpdev->dev.parent->of_node->name, "cdsp")) {
|
||||
dprintk(CVP_ERR,
|
||||
"%s: Failed to probe rpmsg device.Node name:%s\n",
|
||||
__func__, rpdev->dev.parent->of_node->name);
|
||||
err = -EINVAL;
|
||||
goto bail;
|
||||
return -EINVAL;
|
||||
}
|
||||
mutex_lock(&me->smd_mutex);
|
||||
|
||||
mutex_lock(&me->lock);
|
||||
me->chan = rpdev;
|
||||
cdsp_state = me->cdsp_state;
|
||||
cvp_shutdown = me->cvp_shutdown;
|
||||
msg_ptr = cmd_msg.msg_ptr;
|
||||
msg_ptr_len = cmd_msg.msg_ptr_len;
|
||||
mutex_unlock(&me->smd_mutex);
|
||||
me->state = DSP_PROBED;
|
||||
mutex_unlock(&me->lock);
|
||||
|
||||
if (cdsp_state == STATUS_SSR && cvp_shutdown == STATUS_OK) {
|
||||
err = hyp_assign_phys((uint64_t)msg_ptr,
|
||||
msg_ptr_len, srcVM, DEST_VM_NUM, destVM,
|
||||
destVMperm, SRC_VM_NUM);
|
||||
if (err) {
|
||||
dprintk(CVP_ERR,
|
||||
"%s: Failed to hyp_assign. err=%d\n",
|
||||
__func__, err);
|
||||
return err;
|
||||
}
|
||||
schedule_work(&me->ssr_work);
|
||||
mutex_lock(&me->smd_mutex);
|
||||
cdsp_state = me->cdsp_state;
|
||||
mutex_unlock(&me->smd_mutex);
|
||||
}
|
||||
cvp_dsp_send_hfi_queue();
|
||||
|
||||
dprintk(CVP_INFO,
|
||||
"%s: Successfully probed. cdsp_state=%d cvp_shutdown=%d\n",
|
||||
__func__, cdsp_state, cvp_shutdown);
|
||||
bail:
|
||||
return err;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void cvp_dsp_rpmsg_remove(struct rpmsg_device *rpdev)
|
||||
{
|
||||
struct cvp_dsp_apps *me = &gfa_cv;
|
||||
|
||||
cancel_work_sync(&me->ssr_work);
|
||||
mutex_lock(&me->smd_mutex);
|
||||
dprintk(CVP_WARN, "%s: CDSP SSR triggered\n", __func__);
|
||||
|
||||
mutex_lock(&me->lock);
|
||||
cvp_hyp_assign_from_dsp();
|
||||
|
||||
me->chan = NULL;
|
||||
me->cdsp_state = STATUS_SSR;
|
||||
if (me->device) {
|
||||
mutex_lock(&me->device->lock);
|
||||
me->device->dsp_flags &= ~DSP_INIT;
|
||||
mutex_unlock(&me->device->lock);
|
||||
}
|
||||
mutex_unlock(&me->smd_mutex);
|
||||
dprintk(CVP_INFO,
|
||||
"%s: CDSP SSR triggered\n", __func__);
|
||||
me->state = DSP_UNINIT;
|
||||
mutex_unlock(&me->lock);
|
||||
/* kernel driver needs clean all dsp sessions */
|
||||
|
||||
}
|
||||
|
||||
static int cvp_dsp_rpmsg_callback(struct rpmsg_device *rpdev,
|
||||
void *data, int len, void *priv, u32 addr)
|
||||
{
|
||||
struct cvp_dsp_rsp_msg *dsp_response =
|
||||
(struct cvp_dsp_rsp_msg *)data;
|
||||
struct cvp_dsp_rsp_msg *rsp = (struct cvp_dsp_rsp_msg *)data;
|
||||
struct cvp_dsp_apps *me = &gfa_cv;
|
||||
|
||||
dprintk(CVP_DBG,
|
||||
"%s: cmd_msg_type=0x%x dsp_response->ret_val =0x%x\n"
|
||||
, __func__, dsp_response->cmd_msg_type, dsp_response->ret_val);
|
||||
switch (dsp_response->cmd_msg_type) {
|
||||
case CVP_DSP_REGISTER_BUFFER:
|
||||
complete(&me->reg_buffer_work);
|
||||
break;
|
||||
case CVP_DSP_DEREGISTER_BUFFER:
|
||||
complete(&me->dereg_buffer_work);
|
||||
break;
|
||||
case CVP_DSP_SHUTDOWN:
|
||||
complete(&me->shutdown_work);
|
||||
break;
|
||||
case CVP_DSP_SUSPEND:
|
||||
break;
|
||||
case CVP_DSP_RESUME:
|
||||
break;
|
||||
case CVP_DSP_SEND_HFI_CMD_QUEUE:
|
||||
complete(&me->cmdqueue_send_work);
|
||||
break;
|
||||
default:
|
||||
dprintk(CVP_ERR,
|
||||
"%s: Invalid cmd_msg_type received from dsp: %d\n",
|
||||
__func__, dsp_response->cmd_msg_type);
|
||||
break;
|
||||
dprintk(CVP_DBG, "%s: type = 0x%x ret = 0x%x\n",
|
||||
__func__, rsp->type, rsp->ret);
|
||||
|
||||
if (rsp->type >= CVP_DSP_MAX_CMD) {
|
||||
dprintk(CVP_ERR, "%s: Invalid type: %d\n", __func__, rsp->type);
|
||||
return 0;
|
||||
}
|
||||
|
||||
complete(&me->completions[rsp->type]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cvp_dsp_send_cmd_hfi_queue(phys_addr_t *phys_addr,
|
||||
uint32_t size_in_bytes,
|
||||
struct iris_hfi_device *device)
|
||||
{
|
||||
int err, timeout;
|
||||
struct msm_cvp_core *core;
|
||||
struct cvp_dsp_cmd_msg local_cmd_msg;
|
||||
struct cvp_dsp_apps *me = &gfa_cv;
|
||||
int srcVM[SRC_VM_NUM] = {VMID_HLOS};
|
||||
int destVM[DEST_VM_NUM] = {VMID_HLOS, VMID_CDSP_Q6};
|
||||
int destVMperm[DEST_VM_NUM] = { PERM_READ | PERM_WRITE | PERM_EXEC,
|
||||
PERM_READ | PERM_WRITE | PERM_EXEC };
|
||||
|
||||
local_cmd_msg.cmd_msg_type = CVP_DSP_SEND_HFI_CMD_QUEUE;
|
||||
local_cmd_msg.msg_ptr = (uint64_t)phys_addr;
|
||||
local_cmd_msg.msg_ptr_len = size_in_bytes;
|
||||
local_cmd_msg.ddr_type = of_fdt_get_ddrtype();
|
||||
if (local_cmd_msg.ddr_type < 0) {
|
||||
dprintk(CVP_ERR,
|
||||
"%s: Incorrect DDR type value %d\n",
|
||||
__func__, local_cmd_msg.ddr_type);
|
||||
err = -EINVAL;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
mutex_lock(&me->smd_mutex);
|
||||
cmd_msg.msg_ptr = (uint64_t)phys_addr;
|
||||
cmd_msg.msg_ptr_len = (size_in_bytes);
|
||||
me->device = device;
|
||||
mutex_unlock(&me->smd_mutex);
|
||||
|
||||
dprintk(CVP_DBG,
|
||||
"%s: address of buffer, PA=0x%pK size_buff=%d ddr_type=%d\n",
|
||||
__func__, phys_addr, size_in_bytes, local_cmd_msg.ddr_type);
|
||||
|
||||
err = hyp_assign_phys((uint64_t)local_cmd_msg.msg_ptr,
|
||||
local_cmd_msg.msg_ptr_len, srcVM, SRC_VM_NUM, destVM,
|
||||
destVMperm, DEST_VM_NUM);
|
||||
if (err) {
|
||||
dprintk(CVP_ERR,
|
||||
"%s: Failed in hyp_assign. err=%d\n",
|
||||
__func__, err);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
err = cvp_dsp_send_cmd
|
||||
(&local_cmd_msg, sizeof(struct cvp_dsp_cmd_msg));
|
||||
if (err) {
|
||||
dprintk(CVP_ERR,
|
||||
"%s: cvp_dsp_send_cmd faidmesgled with err=%d\n",
|
||||
__func__, err);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
core = list_first_entry(&cvp_driver->cores,
|
||||
struct msm_cvp_core, list);
|
||||
timeout = msecs_to_jiffies(
|
||||
core->resources.msm_cvp_dsp_rsp_timeout);
|
||||
if (!wait_for_completion_timeout(&me->cmdqueue_send_work, timeout)) {
|
||||
dprintk(CVP_ERR, "failed to send cmdqueue\n");
|
||||
err = -ETIMEDOUT;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
mutex_lock(&me->smd_mutex);
|
||||
me->cvp_shutdown = STATUS_OK;
|
||||
me->cdsp_state = STATUS_OK;
|
||||
mutex_unlock(&me->smd_mutex);
|
||||
|
||||
exit:
|
||||
return err;
|
||||
}
|
||||
|
||||
int cvp_dsp_suspend(uint32_t session_flag)
|
||||
{
|
||||
int err = 0;
|
||||
struct cvp_dsp_cmd_msg local_cmd_msg;
|
||||
int rc = 0;
|
||||
struct cvp_dsp_cmd_msg cmd;
|
||||
struct cvp_dsp_apps *me = &gfa_cv;
|
||||
uint32_t cdsp_state;
|
||||
|
||||
mutex_lock(&me->smd_mutex);
|
||||
cdsp_state = me->cdsp_state;
|
||||
mutex_unlock(&me->smd_mutex);
|
||||
cmd.type = CVP_DSP_SUSPEND;
|
||||
|
||||
if (cdsp_state == STATUS_SSR)
|
||||
return 0;
|
||||
mutex_lock(&me->lock);
|
||||
if (me->state != DSP_READY)
|
||||
goto exit;
|
||||
|
||||
local_cmd_msg.cmd_msg_type = CVP_DSP_SUSPEND;
|
||||
err = cvp_dsp_send_cmd
|
||||
(&local_cmd_msg, sizeof(struct cvp_dsp_cmd_msg));
|
||||
if (err != 0)
|
||||
/* Use cvp_dsp_send_cmd_sync after dsp driver is ready */
|
||||
rc = cvp_dsp_send_cmd(&cmd, sizeof(struct cvp_dsp_cmd_msg));
|
||||
if (rc) {
|
||||
dprintk(CVP_ERR,
|
||||
"%s: cvp_dsp_send_cmd failed with err=%d\n",
|
||||
__func__, err);
|
||||
"%s: cvp_dsp_send_cmd failed rc = %d\n",
|
||||
__func__, rc);
|
||||
me->state = DSP_UNINIT;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
return err;
|
||||
me->state = DSP_SUSPEND;
|
||||
|
||||
exit:
|
||||
mutex_unlock(&me->lock);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int cvp_dsp_resume(uint32_t session_flag)
|
||||
{
|
||||
int err;
|
||||
struct cvp_dsp_cmd_msg local_cmd_msg;
|
||||
int rc = 0;
|
||||
struct cvp_dsp_cmd_msg cmd;
|
||||
struct cvp_dsp_apps *me = &gfa_cv;
|
||||
uint32_t cdsp_state;
|
||||
|
||||
mutex_lock(&me->smd_mutex);
|
||||
cdsp_state = me->cdsp_state;
|
||||
mutex_unlock(&me->smd_mutex);
|
||||
cmd.type = CVP_DSP_RESUME;
|
||||
|
||||
if (cdsp_state == STATUS_SSR)
|
||||
return 0;
|
||||
mutex_lock(&me->lock);
|
||||
if (me->state != DSP_SUSPEND)
|
||||
goto exit;
|
||||
|
||||
local_cmd_msg.cmd_msg_type = CVP_DSP_RESUME;
|
||||
err = cvp_dsp_send_cmd
|
||||
(&local_cmd_msg, sizeof(struct cvp_dsp_cmd_msg));
|
||||
if (err != 0)
|
||||
/* Use cvp_dsp_send_cmd_sync after dsp driver is ready */
|
||||
rc = cvp_dsp_send_cmd(&cmd, sizeof(struct cvp_dsp_cmd_msg));
|
||||
if (rc) {
|
||||
dprintk(CVP_ERR,
|
||||
"%s: cvp_dsp_send_cmd failed with err=%d\n",
|
||||
__func__, err);
|
||||
"%s: cvp_dsp_send_cmd failed rc = %d\n",
|
||||
__func__, rc);
|
||||
me->state = DSP_UNINIT;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
me->state = DSP_READY;
|
||||
|
||||
void cvp_dsp_set_cvp_ssr(void)
|
||||
{
|
||||
struct cvp_dsp_apps *me = &gfa_cv;
|
||||
|
||||
mutex_lock(&me->smd_mutex);
|
||||
me->cvp_shutdown = STATUS_SSR;
|
||||
mutex_unlock(&me->smd_mutex);
|
||||
exit:
|
||||
mutex_unlock(&me->lock);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int cvp_dsp_shutdown(uint32_t session_flag)
|
||||
{
|
||||
struct msm_cvp_core *core;
|
||||
struct cvp_dsp_apps *me = &gfa_cv;
|
||||
int err, local_cmd_msg_rsp, timeout;
|
||||
struct cvp_dsp_cmd_msg local_cmd_msg;
|
||||
int srcVM[DEST_VM_NUM] = {VMID_HLOS, VMID_CDSP_Q6};
|
||||
int destVM[SRC_VM_NUM] = {VMID_HLOS};
|
||||
int destVMperm[SRC_VM_NUM] = { PERM_READ | PERM_WRITE | PERM_EXEC };
|
||||
int rc = 0;
|
||||
struct cvp_dsp_cmd_msg cmd;
|
||||
|
||||
local_cmd_msg.cmd_msg_type = CVP_DSP_SHUTDOWN;
|
||||
err = cvp_dsp_send_cmd
|
||||
(&local_cmd_msg, sizeof(struct cvp_dsp_cmd_msg));
|
||||
if (err != 0)
|
||||
cmd.type = CVP_DSP_SHUTDOWN;
|
||||
|
||||
mutex_lock(&me->lock);
|
||||
if (me->state == DSP_INVALID)
|
||||
goto exit;
|
||||
|
||||
me->state = DSP_UNINIT;
|
||||
rc = cvp_dsp_send_cmd_sync(&cmd, sizeof(struct cvp_dsp_cmd_msg));
|
||||
if (rc) {
|
||||
dprintk(CVP_ERR,
|
||||
"%s: cvp_dsp_send_cmd failed with err=%d\n",
|
||||
__func__, err);
|
||||
|
||||
core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list);
|
||||
timeout = msecs_to_jiffies(core->resources.msm_cvp_dsp_rsp_timeout);
|
||||
err = wait_for_completion_timeout(&me->shutdown_work, timeout);
|
||||
if (!err) {
|
||||
dprintk(CVP_ERR, "failed to shutdown dsp\n");
|
||||
return -ETIMEDOUT;
|
||||
"%s: cvp_dsp_send_cmd failed with rc = %d\n",
|
||||
__func__, rc);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
mutex_lock(&me->smd_mutex);
|
||||
local_cmd_msg.msg_ptr = cmd_msg.msg_ptr;
|
||||
local_cmd_msg.msg_ptr_len = cmd_msg.msg_ptr_len;
|
||||
mutex_unlock(&me->smd_mutex);
|
||||
local_cmd_msg_rsp = cmd_msg_rsp.ret_val;
|
||||
if (local_cmd_msg_rsp == 0) {
|
||||
err = hyp_assign_phys((uint64_t)local_cmd_msg.msg_ptr,
|
||||
local_cmd_msg.msg_ptr_len, srcVM, DEST_VM_NUM,
|
||||
destVM, destVMperm, SRC_VM_NUM);
|
||||
if (err) {
|
||||
dprintk(CVP_ERR,
|
||||
"%s: Failed to hyp_assign. err=%d\n",
|
||||
__func__, err);
|
||||
return err;
|
||||
}
|
||||
} else {
|
||||
dprintk(CVP_ERR,
|
||||
"%s: Skipping hyp_assign as CDSP sent invalid response=%d\n",
|
||||
__func__, local_cmd_msg_rsp);
|
||||
}
|
||||
rc = cvp_hyp_assign_from_dsp();
|
||||
|
||||
return err;
|
||||
exit:
|
||||
mutex_unlock(&me->lock);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int cvp_dsp_register_buffer(uint32_t session_id, uint32_t buff_fd,
|
||||
|
|
@ -414,47 +293,37 @@ int cvp_dsp_register_buffer(uint32_t session_id, uint32_t buff_fd,
|
|||
uint32_t buff_offset, uint32_t buff_index,
|
||||
uint32_t buff_fd_iova)
|
||||
{
|
||||
struct cvp_dsp_cmd_msg local_cmd_msg;
|
||||
int err;
|
||||
struct cvp_dsp_cmd_msg cmd;
|
||||
int rc;
|
||||
struct cvp_dsp_apps *me = &gfa_cv;
|
||||
|
||||
local_cmd_msg.cmd_msg_type = CVP_DSP_REGISTER_BUFFER;
|
||||
local_cmd_msg.session_id = session_id;
|
||||
local_cmd_msg.buff_fd = buff_fd;
|
||||
local_cmd_msg.buff_fd_size = buff_fd_size;
|
||||
local_cmd_msg.buff_size = buff_size;
|
||||
local_cmd_msg.buff_offset = buff_offset;
|
||||
local_cmd_msg.buff_index = buff_index;
|
||||
local_cmd_msg.buff_fd_iova = buff_fd_iova;
|
||||
cmd.type = CVP_DSP_REGISTER_BUFFER;
|
||||
cmd.session_id = session_id;
|
||||
cmd.buff_fd = buff_fd;
|
||||
cmd.buff_fd_size = buff_fd_size;
|
||||
cmd.buff_size = buff_size;
|
||||
cmd.buff_offset = buff_offset;
|
||||
cmd.buff_index = buff_index;
|
||||
cmd.buff_fd_iova = buff_fd_iova;
|
||||
|
||||
dprintk(CVP_DBG,
|
||||
"%s: cmd_msg_type=0x%x, buff_fd_iova=0x%x buff_index=0x%x\n",
|
||||
__func__, local_cmd_msg.cmd_msg_type, buff_fd_iova,
|
||||
local_cmd_msg.buff_index);
|
||||
dprintk(CVP_DBG,
|
||||
"%s: buff_size=0x%x session_id=0x%x\n",
|
||||
__func__, local_cmd_msg.buff_size, local_cmd_msg.session_id);
|
||||
"%s: type=0x%x, buff_fd_iova=0x%x buff_index=0x%x\n",
|
||||
__func__, cmd.type, buff_fd_iova,
|
||||
cmd.buff_index);
|
||||
dprintk(CVP_DBG, "%s: buff_size=0x%x session_id=0x%x\n",
|
||||
__func__, cmd.buff_size, cmd.session_id);
|
||||
|
||||
mutex_lock(&me->reg_buffer_mutex);
|
||||
err = cvp_dsp_send_cmd
|
||||
(&local_cmd_msg, sizeof(struct cvp_dsp_cmd_msg));
|
||||
if (err != 0) {
|
||||
dprintk(CVP_ERR,
|
||||
"%s: cvp_dsp_send_cmd failed with err=%d\n",
|
||||
__func__, err);
|
||||
mutex_unlock(&me->reg_buffer_mutex);
|
||||
return err;
|
||||
mutex_lock(&me->lock);
|
||||
rc = cvp_dsp_send_cmd_sync(&cmd, sizeof(struct cvp_dsp_cmd_msg));
|
||||
if (rc) {
|
||||
dprintk(CVP_ERR, "%s send failed rc = %d\n", __func__, rc);
|
||||
me->state = DSP_UNINIT;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
dprintk(CVP_DBG,
|
||||
"%s: calling wait_for_completion work=%pK\n",
|
||||
__func__, &me->reg_buffer_work);
|
||||
wait_for_completion(&me->reg_buffer_work);
|
||||
mutex_unlock(&me->reg_buffer_mutex);
|
||||
dprintk(CVP_DBG,
|
||||
"%s: done calling wait_for_completion\n", __func__);
|
||||
|
||||
return err;
|
||||
exit:
|
||||
mutex_unlock(&me->lock);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int cvp_dsp_deregister_buffer(uint32_t session_id, uint32_t buff_fd,
|
||||
|
|
@ -462,47 +331,37 @@ int cvp_dsp_deregister_buffer(uint32_t session_id, uint32_t buff_fd,
|
|||
uint32_t buff_offset, uint32_t buff_index,
|
||||
uint32_t buff_fd_iova)
|
||||
{
|
||||
struct cvp_dsp_cmd_msg local_cmd_msg;
|
||||
int err;
|
||||
struct cvp_dsp_cmd_msg cmd;
|
||||
int rc;
|
||||
struct cvp_dsp_apps *me = &gfa_cv;
|
||||
|
||||
local_cmd_msg.cmd_msg_type = CVP_DSP_DEREGISTER_BUFFER;
|
||||
local_cmd_msg.session_id = session_id;
|
||||
local_cmd_msg.buff_fd = buff_fd;
|
||||
local_cmd_msg.buff_fd_size = buff_fd_size;
|
||||
local_cmd_msg.buff_size = buff_size;
|
||||
local_cmd_msg.buff_offset = buff_offset;
|
||||
local_cmd_msg.buff_index = buff_index;
|
||||
local_cmd_msg.buff_fd_iova = buff_fd_iova;
|
||||
cmd.type = CVP_DSP_DEREGISTER_BUFFER;
|
||||
cmd.session_id = session_id;
|
||||
cmd.buff_fd = buff_fd;
|
||||
cmd.buff_fd_size = buff_fd_size;
|
||||
cmd.buff_size = buff_size;
|
||||
cmd.buff_offset = buff_offset;
|
||||
cmd.buff_index = buff_index;
|
||||
cmd.buff_fd_iova = buff_fd_iova;
|
||||
|
||||
dprintk(CVP_DBG,
|
||||
"%s: cmd_msg_type=0x%x, buff_fd_iova=0x%x buff_index=0x%x\n",
|
||||
__func__, local_cmd_msg.cmd_msg_type, buff_fd_iova,
|
||||
local_cmd_msg.buff_index);
|
||||
dprintk(CVP_DBG,
|
||||
"%s: buff_size=0x%x session_id=0x%x\n",
|
||||
__func__, local_cmd_msg.buff_size, local_cmd_msg.session_id);
|
||||
"%s: type=0x%x, buff_fd_iova=0x%x buff_index=0x%x\n",
|
||||
__func__, cmd.type, buff_fd_iova,
|
||||
cmd.buff_index);
|
||||
dprintk(CVP_DBG, "%s: buff_size=0x%x session_id=0x%x\n",
|
||||
__func__, cmd.buff_size, cmd.session_id);
|
||||
|
||||
mutex_lock(&me->dereg_buffer_mutex);
|
||||
err = cvp_dsp_send_cmd
|
||||
(&local_cmd_msg, sizeof(struct cvp_dsp_cmd_msg));
|
||||
if (err != 0) {
|
||||
dprintk(CVP_ERR,
|
||||
"%s: cvp_dsp_send_cmd failed with err=%d\n",
|
||||
__func__, err);
|
||||
mutex_unlock(&me->dereg_buffer_mutex);
|
||||
return err;
|
||||
mutex_lock(&me->lock);
|
||||
rc = cvp_dsp_send_cmd_sync(&cmd, sizeof(struct cvp_dsp_cmd_msg));
|
||||
if (rc) {
|
||||
dprintk(CVP_ERR, "%s send failed rc = %d\n", __func__, rc);
|
||||
me->state = DSP_UNINIT;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
dprintk(CVP_DBG,
|
||||
"%s: calling wait_for_completion work=%pK\n",
|
||||
__func__, &me->dereg_buffer_work);
|
||||
wait_for_completion(&me->dereg_buffer_work);
|
||||
dprintk(CVP_DBG,
|
||||
"%s: done calling wait_for_completion\n", __func__);
|
||||
mutex_unlock(&me->dereg_buffer_mutex);
|
||||
|
||||
return err;
|
||||
exit:
|
||||
mutex_unlock(&me->lock);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static const struct rpmsg_device_id cvp_dsp_rpmsg_match[] = {
|
||||
|
|
@ -520,48 +379,102 @@ static struct rpmsg_driver cvp_dsp_rpmsg_client = {
|
|||
},
|
||||
};
|
||||
|
||||
void cvp_dsp_send_hfi_queue(void)
|
||||
{
|
||||
struct msm_cvp_core *core;
|
||||
struct iris_hfi_device *device;
|
||||
struct cvp_dsp_apps *me = &gfa_cv;
|
||||
uint64_t addr;
|
||||
uint32_t size;
|
||||
int rc;
|
||||
|
||||
core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list);
|
||||
if (core)
|
||||
device = core->device->hfi_device_data;
|
||||
else
|
||||
return;
|
||||
|
||||
if (!device) {
|
||||
dprintk(CVP_ERR, "%s: NULL device\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
dprintk(CVP_DBG, "Entering %s\n", __func__);
|
||||
|
||||
mutex_lock(&device->lock);
|
||||
mutex_lock(&me->lock);
|
||||
|
||||
addr = (uint64_t)device->dsp_iface_q_table.mem_data.dma_handle;
|
||||
size = device->dsp_iface_q_table.mem_data.size;
|
||||
|
||||
if (!addr || !size) {
|
||||
dprintk(CVP_DBG, "%s: HFI queue is not ready\n", __func__);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (me->state != DSP_PROBED)
|
||||
goto exit;
|
||||
|
||||
rc = cvp_hyp_assign_to_dsp(addr, size);
|
||||
if (rc) {
|
||||
dprintk(CVP_ERR, "%s: cvp_hyp_assign_to_dsp. rc=%d\n",
|
||||
__func__, rc);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
rc = cvp_dsp_send_cmd_hfi_queue((phys_addr_t *)addr, size);
|
||||
if (rc) {
|
||||
dprintk(CVP_WARN, "%s: Send HFI Queue failed rc = %d\n",
|
||||
__func__, rc);
|
||||
|
||||
rc = cvp_hyp_assign_from_dsp();
|
||||
goto exit;
|
||||
}
|
||||
|
||||
dprintk(CVP_DBG, "%s: dsp initialized\n", __func__);
|
||||
me->state = DSP_READY;
|
||||
|
||||
exit:
|
||||
mutex_unlock(&me->lock);
|
||||
mutex_unlock(&device->lock);
|
||||
}
|
||||
|
||||
int cvp_dsp_device_init(void)
|
||||
{
|
||||
struct cvp_dsp_apps *me = &gfa_cv;
|
||||
int err;
|
||||
int rc;
|
||||
int i;
|
||||
|
||||
if (me->cdsp_state == STATUS_DEINIT) {
|
||||
mutex_init(&me->smd_mutex);
|
||||
mutex_init(&me->reg_buffer_mutex);
|
||||
mutex_init(&me->dereg_buffer_mutex);
|
||||
init_completion(&me->shutdown_work);
|
||||
init_completion(&me->reg_buffer_work);
|
||||
init_completion(&me->dereg_buffer_work);
|
||||
init_completion(&me->cmdqueue_send_work);
|
||||
me->cvp_shutdown = STATUS_INIT;
|
||||
me->cdsp_state = STATUS_INIT;
|
||||
INIT_WORK(&me->ssr_work, msm_cvp_cdsp_ssr_handler);
|
||||
err = register_rpmsg_driver(&cvp_dsp_rpmsg_client);
|
||||
if (err) {
|
||||
dprintk(CVP_ERR,
|
||||
"%s : register_rpmsg failed with err %d\n",
|
||||
__func__, err);
|
||||
goto register_bail;
|
||||
}
|
||||
me->rpmsg_register = 1;
|
||||
mutex_init(&me->lock);
|
||||
me->state = DSP_INVALID;
|
||||
me->hyp_assigned = false;
|
||||
|
||||
for (i = 0; i < CVP_DSP_MAX_CMD; i++)
|
||||
init_completion(&me->completions[i]);
|
||||
|
||||
rc = register_rpmsg_driver(&cvp_dsp_rpmsg_client);
|
||||
if (rc) {
|
||||
dprintk(CVP_ERR,
|
||||
"%s : register_rpmsg_driver failed rc = %d\n",
|
||||
__func__, rc);
|
||||
goto register_bail;
|
||||
}
|
||||
|
||||
me->state = DSP_UNINIT;
|
||||
return 0;
|
||||
|
||||
register_bail:
|
||||
me->cvp_shutdown = STATUS_DEINIT;
|
||||
me->cdsp_state = STATUS_DEINIT;
|
||||
return err;
|
||||
return rc;
|
||||
}
|
||||
|
||||
void cvp_dsp_device_exit(void)
|
||||
{
|
||||
struct cvp_dsp_apps *me = &gfa_cv;
|
||||
|
||||
me->cvp_shutdown = STATUS_DEINIT;
|
||||
me->cdsp_state = STATUS_DEINIT;
|
||||
mutex_destroy(&me->smd_mutex);
|
||||
mutex_destroy(&me->reg_buffer_mutex);
|
||||
mutex_destroy(&me->dereg_buffer_mutex);
|
||||
if (me->rpmsg_register == 1)
|
||||
unregister_rpmsg_driver(&cvp_dsp_rpmsg_client);
|
||||
mutex_lock(&me->lock);
|
||||
me->state = DSP_INVALID;
|
||||
mutex_unlock(&me->lock);
|
||||
|
||||
mutex_destroy(&me->lock);
|
||||
unregister_rpmsg_driver(&cvp_dsp_rpmsg_client);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef MSM_CVP_DSP_H
|
||||
|
|
@ -13,18 +13,48 @@
|
|||
#define CVP_APPS_DSP_GLINK_GUID "cvp-glink-apps-dsp"
|
||||
#define CVP_APPS_DSP_SMD_GUID "cvp-smd-apps-dsp"
|
||||
|
||||
/*
|
||||
* API for CVP driver to send physical address to dsp driver
|
||||
* @param phys_addr
|
||||
* Physical address of command message queue
|
||||
* that needs to be mapped to CDSP.
|
||||
* It should be allocated from CMA adsp_mem region.
|
||||
*
|
||||
* @param size_in_bytes
|
||||
* Size in bytes of command message queue
|
||||
*/
|
||||
int cvp_dsp_send_cmd_hfi_queue(phys_addr_t *phys_addr,
|
||||
uint32_t size_in_bytes, struct iris_hfi_device *device);
|
||||
#define VMID_CDSP_Q6 (30)
|
||||
#define HLOS_VM_NUM 1
|
||||
#define DSP_VM_NUM 2
|
||||
#define CVP_DSP_MAX_RESERVED 5
|
||||
#define CVP_DSP_RESPONSE_TIMEOUT 1000
|
||||
|
||||
int cvp_dsp_device_init(void);
|
||||
void cvp_dsp_device_exit(void);
|
||||
void cvp_dsp_send_hfi_queue(void);
|
||||
|
||||
enum DSP_COMMAND {
|
||||
CVP_DSP_SEND_HFI_QUEUE = 0,
|
||||
CVP_DSP_SUSPEND = 1,
|
||||
CVP_DSP_RESUME = 2,
|
||||
CVP_DSP_SHUTDOWN = 3,
|
||||
CVP_DSP_REGISTER_BUFFER = 4,
|
||||
CVP_DSP_DEREGISTER_BUFFER = 5,
|
||||
CVP_DSP_MAX_CMD
|
||||
};
|
||||
|
||||
struct cvp_dsp_cmd_msg {
|
||||
uint32_t type;
|
||||
int32_t ret;
|
||||
uint64_t msg_ptr;
|
||||
uint32_t msg_ptr_len;
|
||||
uint32_t buff_fd_iova;
|
||||
uint32_t buff_index;
|
||||
uint32_t buff_size;
|
||||
uint32_t session_id;
|
||||
int32_t ddr_type;
|
||||
uint32_t buff_fd;
|
||||
uint32_t buff_offset;
|
||||
uint32_t buff_fd_size;
|
||||
uint32_t reserved1;
|
||||
uint32_t reserved2;
|
||||
};
|
||||
|
||||
struct cvp_dsp_rsp_msg {
|
||||
uint32_t type;
|
||||
int32_t ret;
|
||||
uint32_t reserved[CVP_DSP_MAX_RESERVED];
|
||||
};
|
||||
|
||||
/*
|
||||
* API for CVP driver to suspend CVP session during
|
||||
|
|
@ -53,13 +83,6 @@ int cvp_dsp_resume(uint32_t session_flag);
|
|||
*/
|
||||
int cvp_dsp_shutdown(uint32_t session_flag);
|
||||
|
||||
/*
|
||||
* API for CVP driver to set CVP status during
|
||||
* cvp subsystem error.
|
||||
*
|
||||
*/
|
||||
void cvp_dsp_set_cvp_ssr(void);
|
||||
|
||||
/*
|
||||
* API to register iova buffer address with CDSP
|
||||
*
|
||||
|
|
@ -92,15 +115,5 @@ int cvp_dsp_deregister_buffer(uint32_t session_id, uint32_t buff_fd,
|
|||
uint32_t buff_offset, uint32_t buff_index,
|
||||
uint32_t buff_fd_iova);
|
||||
|
||||
/*
|
||||
* API to initialize CPU and DSP driver interface
|
||||
*/
|
||||
int cvp_dsp_device_init(void);
|
||||
|
||||
/*
|
||||
* API to deinitilized CPU and DSP driver interface
|
||||
*/
|
||||
void cvp_dsp_device_exit(void);
|
||||
|
||||
#endif // MSM_CVP_DSP_H
|
||||
|
||||
|
|
|
|||
|
|
@ -44,10 +44,6 @@
|
|||
#define SYS_MSG_INDEX(__msg) (__msg - SYS_MSG_START)
|
||||
#define SESSION_MSG_INDEX(__msg) (__msg - SESSION_MSG_START)
|
||||
|
||||
#define call_core_op(c, op, args...) \
|
||||
(((c) && (c)->core_ops && (c)->core_ops->op) ? \
|
||||
((c)->core_ops->op(args)) : 0)
|
||||
|
||||
#define ARP_BUF_SIZE 0x100000
|
||||
|
||||
#define CVP_RT_PRIO_THRESHOLD 1
|
||||
|
|
@ -76,6 +72,14 @@ enum instance_state {
|
|||
MSM_CVP_CORE_INVALID
|
||||
};
|
||||
|
||||
enum dsp_state {
|
||||
DSP_INVALID,
|
||||
DSP_UNINIT,
|
||||
DSP_PROBED,
|
||||
DSP_READY,
|
||||
DSP_SUSPEND,
|
||||
};
|
||||
|
||||
struct msm_cvp_list {
|
||||
struct list_head list;
|
||||
struct mutex lock;
|
||||
|
|
@ -314,9 +318,7 @@ struct msm_cvp_core {
|
|||
bool smmu_fault_handled;
|
||||
u32 last_fault_addr;
|
||||
bool trigger_ssr;
|
||||
unsigned long min_freq;
|
||||
unsigned long curr_freq;
|
||||
struct msm_cvp_core_ops *core_ops;
|
||||
atomic64_t kernel_trans_id;
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue