From 224742a390f48c64aac75095c7ac251077f07bdb Mon Sep 17 00:00:00 2001 From: Georgii Staroselskii Date: Tue, 11 Sep 2018 13:31:06 +0300 Subject: [PATCH] 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/include/asm/scu.h | 4 +++ arch/x86/lib/scu.c | 51 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+) diff --git a/arch/x86/include/asm/scu.h b/arch/x86/include/asm/scu.h index 7ce5824167..f5ec5a19d9 100644 --- a/arch/x86/include/asm/scu.h +++ b/arch/x86/include/asm/scu.h @@ -6,6 +6,8 @@ #define _X86_ASM_SCU_IPC_H_ /* IPC defines the following message types */ +#define IPCMSG_INDIRECT_READ 0x02 +#define IPCMSG_INDIRECT_WRITE 0x05 #define IPCMSG_WARM_RESET 0xf0 #define IPCMSG_COLD_RESET 0xf1 #define IPCMSG_SOFT_RESET 0xf2 @@ -23,5 +25,7 @@ struct ipc_ifwi_version { /* Issue commands to the SCU with or without data */ int scu_ipc_simple_command(u32 cmd, u32 sub); int scu_ipc_command(u32 cmd, u32 sub, u32 *in, int inlen, u32 *out, int outlen); +int scu_ipc_raw_command(u32 cmd, u32 sub, u32 *in, int inlen, u32 *out, + int outlen, u32 dptr, u32 sptr); #endif /* _X86_ASM_SCU_IPC_H_ */ diff --git a/arch/x86/lib/scu.c b/arch/x86/lib/scu.c index caa04c688e..af241efe83 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 -- 2.25.1