diff options
author | Tom Rini <trini@konsulko.com> | 2018-09-17 08:04:25 -0400 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2018-09-17 08:04:25 -0400 |
commit | b57f1895b669e3fbdca486e7c40dfea00f22bb93 (patch) | |
tree | 04dc5a27c081aadc2831497e26177f8b4c13056e /arch/x86/lib/scu.c | |
parent | 40e44c8bf516e7071c9b80113473be5757e8c3f3 (diff) | |
parent | 6321da5263b513f1d6959fb721c33970405e6d1d (diff) |
Merge git://git.denx.de/u-boot-x86
Diffstat (limited to 'arch/x86/lib/scu.c')
-rw-r--r-- | arch/x86/lib/scu.c | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/arch/x86/lib/scu.c b/arch/x86/lib/scu.c index caa04c688ee..a6f8297e72e 100644 --- a/arch/x86/lib/scu.c +++ b/arch/x86/lib/scu.c @@ -102,6 +102,57 @@ static int scu_ipc_cmd(struct ipc_regs *regs, u32 cmd, u32 sub, } /** + * scu_ipc_raw_command() - IPC command with data and pointers + * @cmd: IPC command code + * @sub: IPC command sub type + * @in: input data of this IPC command + * @inlen: input data length in dwords + * @out: output data of this IPC command + * @outlen: output data length in dwords + * @dptr: data writing to SPTR register + * @sptr: data writing to DPTR register + * + * Send an IPC command to SCU with input/output data and source/dest pointers. + * + * Return: an IPC error code or 0 on success. + */ +int scu_ipc_raw_command(u32 cmd, u32 sub, u32 *in, int inlen, u32 *out, + int outlen, u32 dptr, u32 sptr) +{ + int inbuflen = DIV_ROUND_UP(inlen, 4); + struct udevice *dev; + struct scu *scu; + int ret; + + ret = syscon_get_by_driver_data(X86_SYSCON_SCU, &dev); + if (ret) + return ret; + + scu = dev_get_priv(dev); + + /* Up to 16 bytes */ + if (inbuflen > 4) + return -EINVAL; + + writel(dptr, &scu->regs->dptr); + writel(sptr, &scu->regs->sptr); + + /* + * SRAM controller doesn't support 8-bit writes, it only + * supports 32-bit writes, so we have to copy input data into + * the temporary buffer, and SCU FW will use the inlen to + * determine the actual input data length in the temporary + * buffer. + */ + + u32 inbuf[4] = {0}; + + memcpy(inbuf, in, inlen); + + return scu_ipc_cmd(scu->regs, cmd, sub, inbuf, inlen, out, outlen); +} + +/** * scu_ipc_simple_command() - send a simple command * @cmd: command * @sub: sub type @@ -129,6 +180,17 @@ int scu_ipc_simple_command(u32 cmd, u32 sub) return scu_ipc_check_status(scu->regs); } +/** + * scu_ipc_command - command with data + * @cmd: command + * @sub: sub type + * @in: input data + * @inlen: input length in dwords + * @out: output data + * @outlen: output length in dwords + * + * Issue a command to the SCU which involves data transfers. + */ int scu_ipc_command(u32 cmd, u32 sub, u32 *in, int inlen, u32 *out, int outlen) { struct scu *scu; |