msm: eva: Fix EVA SSR recovery in DSP
Avoid deadlock in DSP EVA session creation after EVA SSR. Change-Id: I22b363883db5d3bf8e8554a3708cb549437899ba Signed-off-by: George Shen <sqiao@codeaurora.org>
Cette révision appartient à :
@@ -8,6 +8,7 @@
|
||||
#include "msm_cvp_common.h"
|
||||
#include "cvp_core_hfi.h"
|
||||
#include "cvp_hfi_api.h"
|
||||
#include "msm_cvp_dsp.h"
|
||||
|
||||
#define CREATE_TRACE_POINTS
|
||||
#define MAX_SSR_STRING_LEN 10
|
||||
@@ -333,6 +334,30 @@ static int _clk_rate_get(void *data, u64 *val)
|
||||
|
||||
DEFINE_DEBUGFS_ATTRIBUTE(clk_rate_fops, _clk_rate_get, _clk_rate_set, "%llu\n");
|
||||
|
||||
static int _dsp_dbg_set(void *data, u64 val)
|
||||
{
|
||||
|
||||
if (val == 0 || val > (1 << EVA_MEM_DEBUG_ON)) {
|
||||
dprintk(CVP_WARN, "DSP debug mask cannot be %llx\n", val);
|
||||
return 0;
|
||||
}
|
||||
|
||||
gfa_cv.debug_mask = (uint32_t)val;
|
||||
|
||||
cvp_dsp_send_debug_mask();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _dsp_dbg_get(void *data, u64 *val)
|
||||
{
|
||||
*val = gfa_cv.debug_mask;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_DEBUGFS_ATTRIBUTE(dsp_debug_fops, _dsp_dbg_get, _dsp_dbg_set, "%llu\n");
|
||||
|
||||
|
||||
struct dentry *msm_cvp_debugfs_init_core(struct msm_cvp_core *core,
|
||||
struct dentry *parent)
|
||||
@@ -366,6 +391,11 @@ struct dentry *msm_cvp_debugfs_init_core(struct msm_cvp_core *core,
|
||||
dprintk(CVP_ERR, "debugfs_create_file: clock_rate fail\n");
|
||||
goto failed_create_dir;
|
||||
}
|
||||
if (!debugfs_create_file("dsp_debug_level", 0644, dir,
|
||||
NULL, &dsp_debug_fops)) {
|
||||
dprintk(CVP_ERR, "debugfs_create: dsp_debug_level fail\n");
|
||||
goto failed_create_dir;
|
||||
}
|
||||
|
||||
failed_create_dir:
|
||||
return dir;
|
||||
|
@@ -167,11 +167,11 @@ static int cvp_dsp_rpmsg_probe(struct rpmsg_device *rpdev)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
mutex_lock(&me->lock);
|
||||
mutex_lock(&me->tx_lock);
|
||||
me->chan = rpdev;
|
||||
me->state = DSP_PROBED;
|
||||
complete(&me->completions[CPU2DSP_MAX_CMD]);
|
||||
mutex_unlock(&me->lock);
|
||||
mutex_unlock(&me->tx_lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -182,12 +182,12 @@ static void cvp_dsp_rpmsg_remove(struct rpmsg_device *rpdev)
|
||||
|
||||
dprintk(CVP_WARN, "%s: CDSP SSR triggered\n", __func__);
|
||||
|
||||
mutex_lock(&me->lock);
|
||||
mutex_lock(&me->tx_lock);
|
||||
cvp_hyp_assign_from_dsp();
|
||||
|
||||
me->chan = NULL;
|
||||
me->state = DSP_UNINIT;
|
||||
mutex_unlock(&me->lock);
|
||||
mutex_unlock(&me->tx_lock);
|
||||
/* kernel driver needs clean all dsp sessions */
|
||||
|
||||
}
|
||||
@@ -248,7 +248,7 @@ int cvp_dsp_suspend(uint32_t session_flag)
|
||||
|
||||
cmd.type = CPU2DSP_SUSPEND;
|
||||
|
||||
mutex_lock(&me->lock);
|
||||
mutex_lock(&me->tx_lock);
|
||||
if (me->state != DSP_READY)
|
||||
goto exit;
|
||||
|
||||
@@ -269,10 +269,10 @@ retry:
|
||||
|
||||
if (rsp.ret == CPU2DSP_EFATAL) {
|
||||
if (!retried) {
|
||||
mutex_unlock(&me->lock);
|
||||
mutex_unlock(&me->tx_lock);
|
||||
retried = true;
|
||||
rc = cvp_reinit_dsp();
|
||||
mutex_lock(&me->lock);
|
||||
mutex_lock(&me->tx_lock);
|
||||
if (rc)
|
||||
goto fatal_exit;
|
||||
else
|
||||
@@ -290,7 +290,7 @@ fatal_exit:
|
||||
cvp_hyp_assign_from_dsp();
|
||||
rc = -ENOTSUPP;
|
||||
exit:
|
||||
mutex_unlock(&me->lock);
|
||||
mutex_unlock(&me->tx_lock);
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -324,7 +324,7 @@ int cvp_dsp_shutdown(uint32_t session_flag)
|
||||
|
||||
cmd.type = CPU2DSP_SHUTDOWN;
|
||||
|
||||
mutex_lock(&me->lock);
|
||||
mutex_lock(&me->tx_lock);
|
||||
if (me->state == DSP_INVALID)
|
||||
goto exit;
|
||||
|
||||
@@ -341,7 +341,7 @@ int cvp_dsp_shutdown(uint32_t session_flag)
|
||||
rc = cvp_hyp_assign_from_dsp();
|
||||
|
||||
exit:
|
||||
mutex_unlock(&me->lock);
|
||||
mutex_unlock(&me->tx_lock);
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -372,7 +372,7 @@ int cvp_dsp_register_buffer(uint32_t session_id, uint32_t buff_fd,
|
||||
dprintk(CVP_DSP, "%s: buff_size=0x%x session_id=0x%x\n",
|
||||
__func__, cmd.buff_size, cmd.session_id);
|
||||
|
||||
mutex_lock(&me->lock);
|
||||
mutex_lock(&me->tx_lock);
|
||||
retry:
|
||||
rc = cvp_dsp_send_cmd_sync(&cmd, sizeof(struct cvp_dsp_cmd_msg), &rsp);
|
||||
if (rc) {
|
||||
@@ -391,10 +391,10 @@ retry:
|
||||
|
||||
if (rsp.ret == CPU2DSP_EFATAL) {
|
||||
if (!retried) {
|
||||
mutex_unlock(&me->lock);
|
||||
mutex_unlock(&me->tx_lock);
|
||||
retried = true;
|
||||
rc = cvp_reinit_dsp();
|
||||
mutex_lock(&me->lock);
|
||||
mutex_lock(&me->tx_lock);
|
||||
if (rc)
|
||||
goto fatal_exit;
|
||||
else
|
||||
@@ -411,7 +411,7 @@ fatal_exit:
|
||||
cvp_hyp_assign_from_dsp();
|
||||
rc = -ENOTSUPP;
|
||||
exit:
|
||||
mutex_unlock(&me->lock);
|
||||
mutex_unlock(&me->tx_lock);
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -442,7 +442,7 @@ int cvp_dsp_deregister_buffer(uint32_t session_id, uint32_t buff_fd,
|
||||
dprintk(CVP_DSP, "%s: buff_size=0x%x session_id=0x%x\n",
|
||||
__func__, cmd.buff_size, cmd.session_id);
|
||||
|
||||
mutex_lock(&me->lock);
|
||||
mutex_lock(&me->tx_lock);
|
||||
retry:
|
||||
rc = cvp_dsp_send_cmd_sync(&cmd, sizeof(struct cvp_dsp_cmd_msg), &rsp);
|
||||
if (rc) {
|
||||
@@ -461,10 +461,10 @@ retry:
|
||||
|
||||
if (rsp.ret == CPU2DSP_EFATAL) {
|
||||
if (!retried) {
|
||||
mutex_unlock(&me->lock);
|
||||
mutex_unlock(&me->tx_lock);
|
||||
retried = true;
|
||||
rc = cvp_reinit_dsp();
|
||||
mutex_lock(&me->lock);
|
||||
mutex_lock(&me->tx_lock);
|
||||
if (rc)
|
||||
goto fatal_exit;
|
||||
else
|
||||
@@ -481,7 +481,7 @@ fatal_exit:
|
||||
cvp_hyp_assign_from_dsp();
|
||||
rc = -ENOTSUPP;
|
||||
exit:
|
||||
mutex_unlock(&me->lock);
|
||||
mutex_unlock(&me->tx_lock);
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -590,7 +590,7 @@ static int __reinit_dsp(void)
|
||||
return rc;
|
||||
|
||||
/* Resend HFI queue */
|
||||
mutex_lock(&me->lock);
|
||||
mutex_lock(&me->tx_lock);
|
||||
if (!device->dsp_iface_q_table.align_virtual_addr) {
|
||||
dprintk(CVP_ERR, "%s: DSP HFI queue released\n", __func__);
|
||||
rc = -EINVAL;
|
||||
@@ -625,7 +625,7 @@ static int __reinit_dsp(void)
|
||||
rc = -ENODEV;
|
||||
}
|
||||
exit:
|
||||
mutex_unlock(&me->lock);
|
||||
mutex_unlock(&me->tx_lock);
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -636,10 +636,10 @@ static int cvp_reinit_dsp(void)
|
||||
|
||||
rc = __reinit_dsp();
|
||||
if (rc) {
|
||||
mutex_lock(&me->lock);
|
||||
mutex_lock(&me->tx_lock);
|
||||
me->state = DSP_INVALID;
|
||||
cvp_hyp_assign_from_dsp();
|
||||
mutex_unlock(&me->lock);
|
||||
mutex_unlock(&me->tx_lock);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
@@ -929,6 +929,27 @@ static void eva_fastrpc_driver_unregister(uint32_t handle, bool force_exit)
|
||||
}
|
||||
}
|
||||
|
||||
void cvp_dsp_send_debug_mask(void)
|
||||
{
|
||||
struct cvp_dsp_cmd_msg cmd;
|
||||
struct cvp_dsp_apps *me = &gfa_cv;
|
||||
struct cvp_dsp_rsp_msg rsp;
|
||||
int rc;
|
||||
|
||||
cmd.type = CPU2DSP_SET_DEBUG_LEVEL;
|
||||
cmd.eva_dsp_debug_mask = me->debug_mask;
|
||||
|
||||
dprintk(CVP_DSP,
|
||||
"%s: debug mask 0x%x\n",
|
||||
__func__, cmd.eva_dsp_debug_mask);
|
||||
|
||||
rc = cvp_dsp_send_cmd_sync(&cmd, sizeof(struct cvp_dsp_cmd_msg), &rsp);
|
||||
if (rc)
|
||||
dprintk(CVP_ERR,
|
||||
"%s: cvp_dsp_send_cmd failed rc = %d\n",
|
||||
__func__, rc);
|
||||
}
|
||||
|
||||
void cvp_dsp_send_hfi_queue(void)
|
||||
{
|
||||
struct msm_cvp_core *core;
|
||||
@@ -953,13 +974,11 @@ void cvp_dsp_send_hfi_queue(void)
|
||||
dprintk(CVP_DSP, "Entering %s\n", __func__);
|
||||
|
||||
mutex_lock(&device->lock);
|
||||
mutex_lock(&me->lock);
|
||||
mutex_lock(&me->tx_lock);
|
||||
|
||||
if (!device->dsp_iface_q_table.align_virtual_addr) {
|
||||
dprintk(CVP_ERR, "%s: DSP HFI queue released\n", __func__);
|
||||
mutex_unlock(&me->lock);
|
||||
mutex_unlock(&device->lock);
|
||||
return;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
addr = (uint64_t)device->dsp_iface_q_table.mem_data.dma_handle;
|
||||
@@ -1009,20 +1028,20 @@ void cvp_dsp_send_hfi_queue(void)
|
||||
} else if (rsp.ret == CPU2DSP_EINVALSTATE) {
|
||||
dprintk(CVP_ERR, "%s dsp invalid state %d\n",
|
||||
__func__, rsp.dsp_state);
|
||||
mutex_unlock(&me->lock);
|
||||
mutex_unlock(&me->tx_lock);
|
||||
if (cvp_reinit_dsp()) {
|
||||
dprintk(CVP_ERR, "%s reinit dsp fail\n", __func__);
|
||||
mutex_unlock(&device->lock);
|
||||
return;
|
||||
}
|
||||
mutex_lock(&me->lock);
|
||||
mutex_lock(&me->tx_lock);
|
||||
}
|
||||
|
||||
dprintk(CVP_DSP, "%s: dsp initialized\n", __func__);
|
||||
me->state = DSP_READY;
|
||||
|
||||
exit:
|
||||
mutex_unlock(&me->lock);
|
||||
mutex_unlock(&me->tx_lock);
|
||||
mutex_unlock(&device->lock);
|
||||
}
|
||||
/* 32 or 64 bit CPU Side Ptr <-> 2 32 bit DSP Pointers. Dirty Fix. */
|
||||
@@ -1599,7 +1618,7 @@ wait_dsp:
|
||||
if (rc == -ERESTARTSYS) {
|
||||
dprintk(CVP_WARN, "%s received interrupt signal\n", __func__);
|
||||
} else {
|
||||
mutex_lock(&me->lock);
|
||||
mutex_lock(&me->rx_lock);
|
||||
switch (me->pending_dsp2cpu_cmd.type) {
|
||||
case DSP2CPU_POWERON:
|
||||
{
|
||||
@@ -1608,19 +1627,19 @@ wait_dsp:
|
||||
break;
|
||||
}
|
||||
|
||||
mutex_unlock(&me->lock);
|
||||
mutex_lock(&me->tx_lock);
|
||||
old_state = me->state;
|
||||
me->state = DSP_READY;
|
||||
rc = call_hfi_op(hdev, resume, hdev->hfi_device_data);
|
||||
if (rc) {
|
||||
dprintk(CVP_WARN, "%s Failed to resume cvp\n",
|
||||
__func__);
|
||||
mutex_lock(&me->lock);
|
||||
me->state = old_state;
|
||||
mutex_unlock(&me->tx_lock);
|
||||
cmd.ret = 1;
|
||||
break;
|
||||
}
|
||||
mutex_lock(&me->lock);
|
||||
mutex_unlock(&me->tx_lock);
|
||||
cmd.ret = 0;
|
||||
break;
|
||||
}
|
||||
@@ -1678,7 +1697,7 @@ wait_dsp:
|
||||
break;
|
||||
}
|
||||
me->pending_dsp2cpu_cmd.type = CVP_INVALID_RPMSG_TYPE;
|
||||
mutex_unlock(&me->lock);
|
||||
mutex_unlock(&me->rx_lock);
|
||||
}
|
||||
/* Responds to DSP */
|
||||
rc = cvp_dsp_send_cmd(&cmd, sizeof(struct cvp_dsp_cmd_msg));
|
||||
@@ -1700,7 +1719,8 @@ int cvp_dsp_device_init(void)
|
||||
int rc;
|
||||
int i;
|
||||
|
||||
mutex_init(&me->lock);
|
||||
mutex_init(&me->tx_lock);
|
||||
mutex_init(&me->rx_lock);
|
||||
me->state = DSP_INVALID;
|
||||
me->hyp_assigned = false;
|
||||
|
||||
@@ -1739,15 +1759,16 @@ void cvp_dsp_device_exit(void)
|
||||
struct cvp_dsp_apps *me = &gfa_cv;
|
||||
int i;
|
||||
|
||||
mutex_lock(&me->lock);
|
||||
mutex_lock(&me->tx_lock);
|
||||
me->state = DSP_INVALID;
|
||||
mutex_unlock(&me->lock);
|
||||
mutex_unlock(&me->tx_lock);
|
||||
|
||||
DEINIT_MSM_CVP_LIST(&me->fastrpc_driver_list);
|
||||
|
||||
for (i = 0; i <= CPU2DSP_MAX_CMD; i++)
|
||||
complete_all(&me->completions[i]);
|
||||
|
||||
mutex_destroy(&me->lock);
|
||||
mutex_destroy(&me->tx_lock);
|
||||
mutex_destroy(&me->rx_lock);
|
||||
unregister_rpmsg_driver(&cvp_dsp_rpmsg_client);
|
||||
}
|
||||
|
@@ -73,7 +73,7 @@ enum CVP_DSP_COMMAND {
|
||||
CVP_DSP_MAX_CMD = 21,
|
||||
};
|
||||
|
||||
enum eva_dsp_debug_level {
|
||||
enum eva_dsp_debug_bits {
|
||||
EVA_PORT_INFO_ON = 0,
|
||||
EVA_PORT_DEBUG_ON = 1,
|
||||
EVA_QDI_INFO_ON = 2,
|
||||
@@ -123,7 +123,7 @@ struct cvp_dsp_cmd_msg {
|
||||
uint32_t buff_offset;
|
||||
uint32_t buff_fd_size;
|
||||
|
||||
uint32_t eva_dsp_debug_level;
|
||||
uint32_t eva_dsp_debug_mask;
|
||||
|
||||
/* Create Session */
|
||||
uint32_t session_cpu_low;
|
||||
@@ -176,9 +176,16 @@ struct cvp_dsp_fastrpc_driver_entry {
|
||||
};
|
||||
|
||||
struct cvp_dsp_apps {
|
||||
struct mutex lock;
|
||||
/*
|
||||
* tx_lock for sending CPU2DSP cmds or msgs
|
||||
* and dsp state change
|
||||
*/
|
||||
struct mutex tx_lock;
|
||||
/* rx_lock for receiving DSP2CPU cmds or msgs */
|
||||
struct mutex rx_lock;
|
||||
struct rpmsg_device *chan;
|
||||
uint32_t state;
|
||||
uint32_t debug_mask;
|
||||
bool hyp_assigned;
|
||||
uint64_t addr;
|
||||
uint32_t size;
|
||||
@@ -256,5 +263,7 @@ int cvp_dsp_fastrpc_unmap(uint32_t process_id, struct cvp_internal_buf *buf);
|
||||
|
||||
int cvp_dsp_del_sess(uint32_t process_id, struct msm_cvp_inst *inst);
|
||||
|
||||
void cvp_dsp_send_debug_mask(void);
|
||||
|
||||
#endif // MSM_CVP_DSP_H
|
||||
|
||||
|
Référencer dans un nouveau ticket
Bloquer un utilisateur