// SPDX-License-Identifier: GPL-2.0 /* * Driver for the Intel P-Unit Mailbox IPC mechanism * * (C) Copyright 2015 Intel Corporation * * The heart of the P-Unit is the Foxton microcontroller and its firmware, * which provide mailbox interface for power management usage.
*/
staticint intel_punit_ipc_check_status(IPC_DEV *ipcdev, IPC_TYPE type)
{ int loops = CMD_TIMEOUT_SECONDS * USEC_PER_SEC; int errcode; int status;
if (ipcdev->irq) { if (!wait_for_completion_timeout(&ipcdev->cmd_complete,
CMD_TIMEOUT_SECONDS * HZ)) {
dev_err(ipcdev->dev, "IPC timed out\n"); return -ETIMEDOUT;
}
} else { while ((ipc_read_status(ipcdev, type) & CMD_RUN) && --loops)
udelay(1); if (!loops) {
dev_err(ipcdev->dev, "IPC timed out\n"); return -ETIMEDOUT;
}
}
status = ipc_read_status(ipcdev, type);
errcode = status & CMD_ERRCODE_MASK; if (errcode) {
dev_err(ipcdev->dev, "IPC failed: %s, IPC_STS=0x%x\n",
ipc_err_string(errcode), status); return -EIO;
}
return 0;
}
/** * intel_punit_ipc_command() - IPC command with data and pointers * @cmd: IPC command code. * @para1: First 8bit parameter, set 0 if not used. * @para2: Second 8bit parameter, set 0 if not used. * @in: Input data, 32bit for BIOS cmd, two 32bit for GTD and ISPD. * @out: Output data. * * Send a IPC command to P-Unit with data transaction * * Return: IPC error code or 0 on success.
*/ int intel_punit_ipc_command(u32 cmd, u32 para1, u32 para2, u32 *in, u32 *out)
{
IPC_DEV *ipcdev = punit_ipcdev;
IPC_TYPE type;
u32 val; int ret;
mutex_lock(&ipcdev->lock);
reinit_completion(&ipcdev->cmd_complete);
type = (cmd & IPC_PUNIT_CMD_TYPE_MASK) >> IPC_TYPE_OFFSET;
if (in) {
ipc_write_data_low(ipcdev, type, *in); if (type == GTDRIVER_IPC || type == ISPDRIVER_IPC)
ipc_write_data_high(ipcdev, type, *++in);
}
val = cmd & ~IPC_PUNIT_CMD_TYPE_MASK;
val |= CMD_RUN | para2 << CMD_PARA2_SHIFT | para1 << CMD_PARA1_SHIFT;
ipc_write_cmd(ipcdev, type, val);
ret = intel_punit_ipc_check_status(ipcdev, type); if (ret) goto out;
if (out) {
*out = ipc_read_data_low(ipcdev, type); if (type == GTDRIVER_IPC || type == ISPDRIVER_IPC)
*++out = ipc_read_data_high(ipcdev, type);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.