188 lines
4.5 KiB
C
188 lines
4.5 KiB
C
|
|
/* SPDX-License-Identifier: GPL-2.0 */
|
||
|
|
/*
|
||
|
|
* Copyright (c) 2019 MediaTek Inc.
|
||
|
|
*/
|
||
|
|
|
||
|
|
#include <linux/kernel.h>
|
||
|
|
#include <linux/module.h>
|
||
|
|
#include <linux/uaccess.h> /* copy_from/to_user() */
|
||
|
|
|
||
|
|
#include <sspm_ipi.h>
|
||
|
|
#include <trace/events/mtk_events.h>
|
||
|
|
|
||
|
|
#include <mtk_sspm.h>
|
||
|
|
#include <mtk_spm_internal.h>
|
||
|
|
|
||
|
|
|
||
|
|
#define SPM_D_LEN (8) /* # of cmd + arg0 + arg1 + ... */
|
||
|
|
|
||
|
|
int spm_to_sspm_command_async(u32 cmd, struct spm_data *spm_d)
|
||
|
|
{
|
||
|
|
unsigned int ret = 0;
|
||
|
|
|
||
|
|
switch (cmd) {
|
||
|
|
case SPM_DPIDLE_ENTER:
|
||
|
|
case SPM_DPIDLE_LEAVE:
|
||
|
|
case SPM_ENTER_SODI:
|
||
|
|
case SPM_LEAVE_SODI:
|
||
|
|
case SPM_ENTER_SODI3:
|
||
|
|
case SPM_LEAVE_SODI3:
|
||
|
|
spm_d->cmd = cmd;
|
||
|
|
ret = sspm_ipi_send_async(
|
||
|
|
IPI_ID_SPM_SUSPEND, IPI_OPT_DEFAUT, spm_d, SPM_D_LEN);
|
||
|
|
if (ret != 0)
|
||
|
|
printk_deferred("[name:spm&]#@# %s(%d) sspm_ipi_send_async(cmd:0x%x) ret %d\n",
|
||
|
|
__func__, __LINE__, cmd, ret);
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
printk_deferred("[name:spm&]#@# %s(%d) cmd(%d) wrong!!!\n",
|
||
|
|
__func__, __LINE__, cmd);
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
|
||
|
|
return ret;
|
||
|
|
}
|
||
|
|
|
||
|
|
int spm_to_sspm_command_async_wait(u32 cmd)
|
||
|
|
{
|
||
|
|
int ack_data = 0;
|
||
|
|
unsigned int ret = 0;
|
||
|
|
|
||
|
|
switch (cmd) {
|
||
|
|
case SPM_DPIDLE_ENTER:
|
||
|
|
case SPM_DPIDLE_LEAVE:
|
||
|
|
case SPM_ENTER_SODI:
|
||
|
|
case SPM_LEAVE_SODI:
|
||
|
|
case SPM_ENTER_SODI3:
|
||
|
|
case SPM_LEAVE_SODI3:
|
||
|
|
ret = sspm_ipi_send_async_wait(
|
||
|
|
IPI_ID_SPM_SUSPEND, IPI_OPT_DEFAUT, &ack_data);
|
||
|
|
if (ret != 0) {
|
||
|
|
printk_deferred("[name:spm&]#@# %s(%d) sspm_ipi_send_async_wait(cmd:0x%x) ret %d\n",
|
||
|
|
__func__, __LINE__, cmd, ret);
|
||
|
|
} else if (ack_data < 0) {
|
||
|
|
ret = ack_data;
|
||
|
|
printk_deferred("[name:spm&]#@# %s(%d) cmd(%d) return %d\n",
|
||
|
|
__func__, __LINE__, cmd, ret);
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
printk_deferred("[name:spm&]#@# %s(%d) cmd(%d) wrong!!!\n",
|
||
|
|
__func__, __LINE__, cmd);
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
|
||
|
|
return ret;
|
||
|
|
}
|
||
|
|
|
||
|
|
int spm_to_sspm_command(u32 cmd, struct spm_data *spm_d)
|
||
|
|
{
|
||
|
|
int ack_data = 0;
|
||
|
|
unsigned int ret = 0;
|
||
|
|
/* struct spm_data _spm_d; */
|
||
|
|
|
||
|
|
switch (cmd) {
|
||
|
|
case SPM_SUSPEND:
|
||
|
|
case SPM_RESUME:
|
||
|
|
case SPM_DPIDLE_ENTER:
|
||
|
|
case SPM_DPIDLE_LEAVE:
|
||
|
|
case SPM_ENTER_SODI:
|
||
|
|
case SPM_ENTER_SODI3:
|
||
|
|
case SPM_LEAVE_SODI:
|
||
|
|
case SPM_LEAVE_SODI3:
|
||
|
|
spm_d->cmd = cmd;
|
||
|
|
ret = sspm_ipi_send_sync(
|
||
|
|
IPI_ID_SPM_SUSPEND, IPI_OPT_POLLING, spm_d, SPM_D_LEN,
|
||
|
|
&ack_data, 1);
|
||
|
|
if (ret != 0) {
|
||
|
|
printk_deferred("[name:spm&]#@# %s(%d) cmd:0x%x ret %d\n",
|
||
|
|
__func__, __LINE__, cmd, ret);
|
||
|
|
} else if (ack_data < 0) {
|
||
|
|
ret = ack_data;
|
||
|
|
printk_deferred("[name:spm&]#@# %s(%d) cmd:0x%x ret %d\n",
|
||
|
|
__func__, __LINE__, cmd, ret);
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
case SPM_VCORE_PWARP_CMD:
|
||
|
|
spm_d->cmd = cmd;
|
||
|
|
ret = sspm_ipi_send_sync(
|
||
|
|
IPI_ID_SPM_SUSPEND, IPI_OPT_POLLING, spm_d, SPM_D_LEN,
|
||
|
|
&ack_data, 1);
|
||
|
|
if (ret != 0) {
|
||
|
|
printk_deferred("[name:spm&]#@# %s(%d) cmd:0x%x ret %d\n",
|
||
|
|
__func__, __LINE__, cmd, ret);
|
||
|
|
} else if (ack_data < 0) {
|
||
|
|
ret = ack_data;
|
||
|
|
printk_deferred("[name:spm&]#@# %s(%d) cmd:0x%x ret %d\n",
|
||
|
|
__func__, __LINE__, cmd, ret);
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
case SPM_SUSPEND_PREPARE:
|
||
|
|
case SPM_POST_SUSPEND:
|
||
|
|
spm_d->cmd = cmd;
|
||
|
|
ret = sspm_ipi_send_sync(
|
||
|
|
IPI_ID_SPM_SUSPEND, IPI_OPT_POLLING, spm_d, SPM_D_LEN,
|
||
|
|
&ack_data, 1);
|
||
|
|
if (ret != 0) {
|
||
|
|
printk_deferred("[name:spm&]#@# %s(%d) cmd:0x%x ret %d\n",
|
||
|
|
__func__, __LINE__, cmd, ret);
|
||
|
|
} else if (ack_data < 0) {
|
||
|
|
ret = ack_data;
|
||
|
|
printk_deferred("[name:spm&]#@# %s(%d) cmd:0x%x ret %d\n",
|
||
|
|
__func__, __LINE__, cmd, ret);
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
case SPM_DPIDLE_PREPARE:
|
||
|
|
case SPM_POST_DPIDLE:
|
||
|
|
spm_d->cmd = cmd;
|
||
|
|
ret = sspm_ipi_send_sync(
|
||
|
|
IPI_ID_SPM_SUSPEND, IPI_OPT_POLLING, spm_d, SPM_D_LEN,
|
||
|
|
&ack_data, 1);
|
||
|
|
if (ret != 0) {
|
||
|
|
printk_deferred("[name:spm&]#@# %s(%d) cmd:0x%x ret %d\n",
|
||
|
|
__func__, __LINE__, cmd, ret);
|
||
|
|
} else if (ack_data < 0) {
|
||
|
|
ret = ack_data;
|
||
|
|
printk_deferred("[name:spm&]#@# %s(%d) cmd:0x%x ret %d\n",
|
||
|
|
__func__, __LINE__, cmd, ret);
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
case SPM_SODI_PREPARE:
|
||
|
|
case SPM_POST_SODI:
|
||
|
|
case SPM_TWAM_ENABLE:
|
||
|
|
spm_d->cmd = cmd;
|
||
|
|
ret = sspm_ipi_send_sync(
|
||
|
|
IPI_ID_SPM_SUSPEND, IPI_OPT_POLLING, spm_d, SPM_D_LEN,
|
||
|
|
&ack_data, 1);
|
||
|
|
if (ret != 0) {
|
||
|
|
printk_deferred("[name:spm&]#@# %s(%d) cmd:0x%x ret %d\n",
|
||
|
|
__func__, __LINE__, cmd, ret);
|
||
|
|
} else if (ack_data < 0) {
|
||
|
|
ret = ack_data;
|
||
|
|
printk_deferred("[name:spm&]#@# %s(%d) cmd:0x%x ret %d\n",
|
||
|
|
__func__, __LINE__, cmd, ret);
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
printk_deferred("[name:spm&]#@# %s(%d) cmd(%d) wrong!!!\n",
|
||
|
|
__func__, __LINE__, cmd);
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
|
||
|
|
return ret;
|
||
|
|
}
|
||
|
|
|
||
|
|
//Fix me
|
||
|
|
static atomic_t ipi_lock_cnt;
|
||
|
|
bool is_sspm_ipi_lock_spm(void)
|
||
|
|
{
|
||
|
|
int lock_cnt = -1;
|
||
|
|
bool ret = false;
|
||
|
|
|
||
|
|
lock_cnt = atomic_read(&ipi_lock_cnt);
|
||
|
|
|
||
|
|
ret = (lock_cnt == 0) ? false : true;
|
||
|
|
|
||
|
|
return ret;
|
||
|
|
}
|