mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-08 21:22:09 -04:00
Merge "msm: cvp: Support DSP to CPU reverse rpmsg"
This commit is contained in:
commit
a22aea40af
3 changed files with 171 additions and 31 deletions
|
|
@ -2575,7 +2575,10 @@ static void iris_hfi_pm_handler(struct work_struct *work)
|
|||
}
|
||||
|
||||
mutex_lock(&device->lock);
|
||||
rc = __power_collapse(device, false);
|
||||
if (gfa_cv.state == DSP_SUSPEND)
|
||||
rc = __power_collapse(device, true);
|
||||
else
|
||||
rc = __power_collapse(device, false);
|
||||
mutex_unlock(&device->lock);
|
||||
switch (rc) {
|
||||
case 0:
|
||||
|
|
@ -2693,7 +2696,7 @@ exit:
|
|||
return rc;
|
||||
|
||||
skip_power_off:
|
||||
dprintk(CVP_WARN, "Skip PC(%#x, %#x, %#x)\n",
|
||||
dprintk(CVP_PWR, "Skip PC(%#x, %#x, %#x)\n",
|
||||
wfi_status, idle_status, pc_ready);
|
||||
__flush_debug_queue(device, device->raw_packet);
|
||||
return -EAGAIN;
|
||||
|
|
|
|||
|
|
@ -10,17 +10,7 @@
|
|||
#include "msm_cvp_dsp.h"
|
||||
#include "msm_cvp_internal.h"
|
||||
|
||||
struct cvp_dsp_apps {
|
||||
struct mutex lock;
|
||||
struct rpmsg_device *chan;
|
||||
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;
|
||||
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,
|
||||
|
|
@ -71,6 +61,8 @@ static int cvp_dsp_send_cmd_sync(struct cvp_dsp_cmd_msg *cmd, uint32_t len)
|
|||
goto exit;
|
||||
}
|
||||
|
||||
me->pending_dsp2cpu_rsp.type = CVP_INVALID_RPMSG_TYPE;
|
||||
|
||||
exit:
|
||||
return rc;
|
||||
}
|
||||
|
|
@ -81,7 +73,7 @@ static int cvp_dsp_send_cmd_hfi_queue(phys_addr_t *phys_addr,
|
|||
int rc = 0;
|
||||
struct cvp_dsp_cmd_msg cmd;
|
||||
|
||||
cmd.type = CVP_DSP_SEND_HFI_QUEUE;
|
||||
cmd.type = CPU2DSP_SEND_HFI_QUEUE;
|
||||
cmd.msg_ptr = (uint64_t)phys_addr;
|
||||
cmd.msg_ptr_len = size_in_bytes;
|
||||
cmd.ddr_type = of_fdt_get_ddrtype();
|
||||
|
|
@ -193,12 +185,34 @@ static int cvp_dsp_rpmsg_callback(struct rpmsg_device *rpdev,
|
|||
dprintk(CVP_DSP, "%s: type = 0x%x ret = 0x%x\n",
|
||||
__func__, rsp->type, rsp->ret);
|
||||
|
||||
if (rsp->type >= CVP_DSP_MAX_CMD) {
|
||||
if (rsp->type == CPU2DSP_SUSPEND ||
|
||||
rsp->type == CPU2DSP_RESUME) {
|
||||
me->pending_dsp2cpu_rsp.type = CVP_INVALID_RPMSG_TYPE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (me->pending_dsp2cpu_rsp.type != CVP_INVALID_RPMSG_TYPE ||
|
||||
me->pending_dsp2cpu_cmd.type != CVP_INVALID_RPMSG_TYPE)
|
||||
goto exit;
|
||||
|
||||
if (rsp->type < CPU2DSP_MAX_CMD) {
|
||||
memcpy(&me->pending_dsp2cpu_rsp, rsp,
|
||||
sizeof(struct cvp_dsp_rsp_msg));
|
||||
complete(&me->completions[rsp->type]);
|
||||
} else if (rsp->type < CVP_DSP_MAX_CMD) {
|
||||
memcpy(&me->pending_dsp2cpu_cmd, rsp,
|
||||
sizeof(struct cvp_dsp2cpu_cmd_msg));
|
||||
complete(&me->completions[CPU2DSP_MAX_CMD]);
|
||||
} else {
|
||||
dprintk(CVP_ERR, "%s: Invalid type: %d\n", __func__, rsp->type);
|
||||
return 0;
|
||||
}
|
||||
|
||||
complete(&me->completions[rsp->type]);
|
||||
return 0;
|
||||
exit:
|
||||
dprintk(CVP_ERR, "concurrent dsp cmd type = %d, rsp type = %d\n",
|
||||
me->pending_dsp2cpu_cmd.type,
|
||||
me->pending_dsp2cpu_rsp.type);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -208,7 +222,7 @@ int cvp_dsp_suspend(uint32_t session_flag)
|
|||
struct cvp_dsp_cmd_msg cmd;
|
||||
struct cvp_dsp_apps *me = &gfa_cv;
|
||||
|
||||
cmd.type = CVP_DSP_SUSPEND;
|
||||
cmd.type = CPU2DSP_SUSPEND;
|
||||
|
||||
mutex_lock(&me->lock);
|
||||
if (me->state != DSP_READY)
|
||||
|
|
@ -237,7 +251,7 @@ int cvp_dsp_resume(uint32_t session_flag)
|
|||
struct cvp_dsp_cmd_msg cmd;
|
||||
struct cvp_dsp_apps *me = &gfa_cv;
|
||||
|
||||
cmd.type = CVP_DSP_RESUME;
|
||||
cmd.type = CPU2DSP_RESUME;
|
||||
|
||||
mutex_lock(&me->lock);
|
||||
if (me->state != DSP_SUSPEND)
|
||||
|
|
@ -266,7 +280,7 @@ int cvp_dsp_shutdown(uint32_t session_flag)
|
|||
int rc = 0;
|
||||
struct cvp_dsp_cmd_msg cmd;
|
||||
|
||||
cmd.type = CVP_DSP_SHUTDOWN;
|
||||
cmd.type = CPU2DSP_SHUTDOWN;
|
||||
|
||||
mutex_lock(&me->lock);
|
||||
if (me->state == DSP_INVALID)
|
||||
|
|
@ -297,7 +311,7 @@ int cvp_dsp_register_buffer(uint32_t session_id, uint32_t buff_fd,
|
|||
int rc;
|
||||
struct cvp_dsp_apps *me = &gfa_cv;
|
||||
|
||||
cmd.type = CVP_DSP_REGISTER_BUFFER;
|
||||
cmd.type = CPU2DSP_REGISTER_BUFFER;
|
||||
cmd.session_id = session_id;
|
||||
cmd.buff_fd = buff_fd;
|
||||
cmd.buff_fd_size = buff_fd_size;
|
||||
|
|
@ -335,7 +349,7 @@ int cvp_dsp_deregister_buffer(uint32_t session_id, uint32_t buff_fd,
|
|||
int rc;
|
||||
struct cvp_dsp_apps *me = &gfa_cv;
|
||||
|
||||
cmd.type = CVP_DSP_DEREGISTER_BUFFER;
|
||||
cmd.type = CPU2DSP_DEREGISTER_BUFFER;
|
||||
cmd.session_id = session_id;
|
||||
cmd.buff_fd = buff_fd;
|
||||
cmd.buff_fd_size = buff_fd_size;
|
||||
|
|
@ -439,9 +453,93 @@ exit:
|
|||
mutex_unlock(&device->lock);
|
||||
}
|
||||
|
||||
static int cvp_dsp_thread(void *data)
|
||||
{
|
||||
int rc = 0, old_state;
|
||||
struct cvp_dsp_apps *me = &gfa_cv;
|
||||
struct cvp_dsp_cmd_msg cmd;
|
||||
struct cvp_hfi_device *hdev;
|
||||
struct msm_cvp_core *core;
|
||||
|
||||
core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list);
|
||||
if (!core) {
|
||||
dprintk(CVP_ERR, "%s: Failed to find core\n", __func__);
|
||||
rc = -EINVAL;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
hdev = (struct cvp_hfi_device *)core->device;
|
||||
if (!hdev) {
|
||||
dprintk(CVP_ERR, "%s Invalid device handle\n", __func__);
|
||||
rc = -EINVAL;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
wait_dsp:
|
||||
rc = wait_for_completion_interruptible(
|
||||
&me->completions[CPU2DSP_MAX_CMD]);
|
||||
|
||||
if (me->state == DSP_INVALID)
|
||||
goto exit;
|
||||
|
||||
cmd.type = me->pending_dsp2cpu_cmd.type;
|
||||
|
||||
if (rc == -ERESTARTSYS) {
|
||||
dprintk(CVP_WARN, "%s received interrupt signal\n", __func__);
|
||||
} else {
|
||||
mutex_lock(&me->lock);
|
||||
switch (me->pending_dsp2cpu_cmd.type) {
|
||||
case DSP2CPU_POWERON:
|
||||
{
|
||||
if (me->state == DSP_READY)
|
||||
break;
|
||||
|
||||
mutex_unlock(&me->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;
|
||||
cmd.ret = 1;
|
||||
break;
|
||||
}
|
||||
mutex_lock(&me->lock);
|
||||
cmd.ret = 0;
|
||||
break;
|
||||
}
|
||||
case DSP2CPU_POWEROFF:
|
||||
{
|
||||
me->state = DSP_SUSPEND;
|
||||
cmd.ret = 0;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
dprintk(CVP_ERR, "unrecognaized dsp cmds: %d\n",
|
||||
me->pending_dsp2cpu_cmd.type);
|
||||
break;
|
||||
}
|
||||
me->pending_dsp2cpu_cmd.type = CVP_INVALID_RPMSG_TYPE;
|
||||
mutex_unlock(&me->lock);
|
||||
}
|
||||
/* Responds to DSP */
|
||||
rc = cvp_dsp_send_cmd(&cmd, sizeof(struct cvp_dsp_cmd_msg));
|
||||
if (rc)
|
||||
dprintk(CVP_ERR,
|
||||
"%s: cvp_dsp_send_cmd failed rc = %d cmd type=%d\n",
|
||||
__func__, rc, cmd.type);
|
||||
goto wait_dsp;
|
||||
exit:
|
||||
dprintk(CVP_DBG, "dsp thread exit\n");
|
||||
do_exit(rc);
|
||||
}
|
||||
|
||||
int cvp_dsp_device_init(void)
|
||||
{
|
||||
struct cvp_dsp_apps *me = &gfa_cv;
|
||||
char tname[16];
|
||||
int rc;
|
||||
int i;
|
||||
|
||||
|
|
@ -449,9 +547,12 @@ int cvp_dsp_device_init(void)
|
|||
me->state = DSP_INVALID;
|
||||
me->hyp_assigned = false;
|
||||
|
||||
for (i = 0; i < CVP_DSP_MAX_CMD; i++)
|
||||
for (i = 0; i <= CPU2DSP_MAX_CMD; i++)
|
||||
init_completion(&me->completions[i]);
|
||||
|
||||
me->pending_dsp2cpu_cmd.type = CVP_INVALID_RPMSG_TYPE;
|
||||
me->pending_dsp2cpu_rsp.type = CVP_INVALID_RPMSG_TYPE;
|
||||
|
||||
rc = register_rpmsg_driver(&cvp_dsp_rpmsg_client);
|
||||
if (rc) {
|
||||
dprintk(CVP_ERR,
|
||||
|
|
@ -459,7 +560,13 @@ int cvp_dsp_device_init(void)
|
|||
__func__, rc);
|
||||
goto register_bail;
|
||||
}
|
||||
|
||||
snprintf(tname, sizeof(tname), "cvp-dsp-thread");
|
||||
me->dsp_thread = kthread_run(cvp_dsp_thread, me, tname);
|
||||
if (!me->dsp_thread) {
|
||||
dprintk(CVP_ERR, "%s create %s fail", __func__, tname);
|
||||
rc = -ECHILD;
|
||||
goto register_bail;
|
||||
}
|
||||
me->state = DSP_UNINIT;
|
||||
return 0;
|
||||
|
||||
|
|
@ -470,11 +577,15 @@ register_bail:
|
|||
void cvp_dsp_device_exit(void)
|
||||
{
|
||||
struct cvp_dsp_apps *me = &gfa_cv;
|
||||
int i;
|
||||
|
||||
mutex_lock(&me->lock);
|
||||
me->state = DSP_INVALID;
|
||||
mutex_unlock(&me->lock);
|
||||
|
||||
for (i = 0; i <= CPU2DSP_MAX_CMD; i++)
|
||||
complete_all(&me->completions[i]);
|
||||
|
||||
mutex_destroy(&me->lock);
|
||||
unregister_rpmsg_driver(&cvp_dsp_rpmsg_client);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,20 +17,25 @@
|
|||
#define HLOS_VM_NUM 1
|
||||
#define DSP_VM_NUM 2
|
||||
#define CVP_DSP_MAX_RESERVED 5
|
||||
#define CVP_DSP2CPU_RESERVED 8
|
||||
#define CVP_DSP_RESPONSE_TIMEOUT 1000
|
||||
#define CVP_INVALID_RPMSG_TYPE 0xBADDFACE
|
||||
|
||||
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
|
||||
enum CVP_DSP_COMMAND {
|
||||
CPU2DSP_SEND_HFI_QUEUE = 0,
|
||||
CPU2DSP_SUSPEND = 1,
|
||||
CPU2DSP_RESUME = 2,
|
||||
CPU2DSP_SHUTDOWN = 3,
|
||||
CPU2DSP_REGISTER_BUFFER = 4,
|
||||
CPU2DSP_DEREGISTER_BUFFER = 5,
|
||||
CPU2DSP_MAX_CMD = 6,
|
||||
DSP2CPU_POWERON = 6,
|
||||
DSP2CPU_POWEROFF = 7,
|
||||
CVP_DSP_MAX_CMD = 8,
|
||||
};
|
||||
|
||||
struct cvp_dsp_cmd_msg {
|
||||
|
|
@ -56,6 +61,27 @@ struct cvp_dsp_rsp_msg {
|
|||
uint32_t reserved[CVP_DSP_MAX_RESERVED];
|
||||
};
|
||||
|
||||
struct cvp_dsp2cpu_cmd_msg {
|
||||
uint32_t type;
|
||||
uint32_t ver;
|
||||
uint32_t len;
|
||||
uint32_t data[CVP_DSP2CPU_RESERVED];
|
||||
};
|
||||
|
||||
struct cvp_dsp_apps {
|
||||
struct mutex lock;
|
||||
struct rpmsg_device *chan;
|
||||
uint32_t state;
|
||||
bool hyp_assigned;
|
||||
uint64_t addr;
|
||||
uint32_t size;
|
||||
struct completion completions[CPU2DSP_MAX_CMD + 1];
|
||||
struct cvp_dsp2cpu_cmd_msg pending_dsp2cpu_cmd;
|
||||
struct cvp_dsp_rsp_msg pending_dsp2cpu_rsp;
|
||||
struct task_struct *dsp_thread;
|
||||
};
|
||||
|
||||
extern struct cvp_dsp_apps gfa_cv;
|
||||
/*
|
||||
* API for CVP driver to suspend CVP session during
|
||||
* power collapse
|
||||
|
|
|
|||
Loading…
Reference in a new issue