From 224742a390f48c64aac75095c7ac251077f07bdb Mon Sep 17 00:00:00 2001 From: Georgii Staroselskii Date: Tue, 11 Sep 2018 13:31:06 +0300 Subject: x86: cpu: introduce scu_ipc_raw_command() This interface will be used to configure properly some pins on Merrifield that are shared with SCU. scu_ipc_raw_command() writes SPTR and DPTR registers before sending a command to SCU. This code has been ported from Linux work done by Andy Shevchenko. Signed-off-by: Georgii Staroselskii Reviewed-by: Andy Shevchenko Reviewed-by: Bin Meng --- arch/x86/lib/scu.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) (limited to 'arch/x86/lib/scu.c') diff --git a/arch/x86/lib/scu.c b/arch/x86/lib/scu.c index caa04c688ee..af241efe83d 100644 --- a/arch/x86/lib/scu.c +++ b/arch/x86/lib/scu.c @@ -101,6 +101,57 @@ static int scu_ipc_cmd(struct ipc_regs *regs, u32 cmd, u32 sub, return err; } +/** + * 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 -- cgit v1.2.3 From 6321da5263b513f1d6959fb721c33970405e6d1d Mon Sep 17 00:00:00 2001 From: Georgii Staroselskii Date: Tue, 11 Sep 2018 13:31:10 +0300 Subject: x86: cpu: add docstring to scu_ipc_command() These comments were copied from the Linux kernel driver in drivers/platform/x86/intel_scu_ipc.c Signed-off-by: Georgii Staroselskii Reviewed-by: Andy Shevchenko Reviewed-by: Bin Meng --- arch/x86/lib/scu.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'arch/x86/lib/scu.c') diff --git a/arch/x86/lib/scu.c b/arch/x86/lib/scu.c index af241efe83d..a6f8297e72e 100644 --- a/arch/x86/lib/scu.c +++ b/arch/x86/lib/scu.c @@ -180,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; -- cgit v1.2.3