Commit 224742a390f48c64aac75095c7ac251077f07bdb

Authored by Georgii Staroselskii
Committed by Bin Meng
1 parent 41f4e4302f

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 <georgii.staroselskii@emlid.com>
Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>

Showing 2 changed files with 55 additions and 0 deletions Side-by-side Diff

arch/x86/include/asm/scu.h
... ... @@ -6,6 +6,8 @@
6 6 #define _X86_ASM_SCU_IPC_H_
7 7  
8 8 /* IPC defines the following message types */
  9 +#define IPCMSG_INDIRECT_READ 0x02
  10 +#define IPCMSG_INDIRECT_WRITE 0x05
9 11 #define IPCMSG_WARM_RESET 0xf0
10 12 #define IPCMSG_COLD_RESET 0xf1
11 13 #define IPCMSG_SOFT_RESET 0xf2
... ... @@ -23,6 +25,8 @@
23 25 /* Issue commands to the SCU with or without data */
24 26 int scu_ipc_simple_command(u32 cmd, u32 sub);
25 27 int scu_ipc_command(u32 cmd, u32 sub, u32 *in, int inlen, u32 *out, int outlen);
  28 +int scu_ipc_raw_command(u32 cmd, u32 sub, u32 *in, int inlen, u32 *out,
  29 + int outlen, u32 dptr, u32 sptr);
26 30  
27 31 #endif /* _X86_ASM_SCU_IPC_H_ */
... ... @@ -102,6 +102,57 @@
102 102 }
103 103  
104 104 /**
  105 + * scu_ipc_raw_command() - IPC command with data and pointers
  106 + * @cmd: IPC command code
  107 + * @sub: IPC command sub type
  108 + * @in: input data of this IPC command
  109 + * @inlen: input data length in dwords
  110 + * @out: output data of this IPC command
  111 + * @outlen: output data length in dwords
  112 + * @dptr: data writing to SPTR register
  113 + * @sptr: data writing to DPTR register
  114 + *
  115 + * Send an IPC command to SCU with input/output data and source/dest pointers.
  116 + *
  117 + * Return: an IPC error code or 0 on success.
  118 + */
  119 +int scu_ipc_raw_command(u32 cmd, u32 sub, u32 *in, int inlen, u32 *out,
  120 + int outlen, u32 dptr, u32 sptr)
  121 +{
  122 + int inbuflen = DIV_ROUND_UP(inlen, 4);
  123 + struct udevice *dev;
  124 + struct scu *scu;
  125 + int ret;
  126 +
  127 + ret = syscon_get_by_driver_data(X86_SYSCON_SCU, &dev);
  128 + if (ret)
  129 + return ret;
  130 +
  131 + scu = dev_get_priv(dev);
  132 +
  133 + /* Up to 16 bytes */
  134 + if (inbuflen > 4)
  135 + return -EINVAL;
  136 +
  137 + writel(dptr, &scu->regs->dptr);
  138 + writel(sptr, &scu->regs->sptr);
  139 +
  140 + /*
  141 + * SRAM controller doesn't support 8-bit writes, it only
  142 + * supports 32-bit writes, so we have to copy input data into
  143 + * the temporary buffer, and SCU FW will use the inlen to
  144 + * determine the actual input data length in the temporary
  145 + * buffer.
  146 + */
  147 +
  148 + u32 inbuf[4] = {0};
  149 +
  150 + memcpy(inbuf, in, inlen);
  151 +
  152 + return scu_ipc_cmd(scu->regs, cmd, sub, inbuf, inlen, out, outlen);
  153 +}
  154 +
  155 +/**
105 156 * scu_ipc_simple_command() - send a simple command
106 157 * @cmd: command
107 158 * @sub: sub type