Commit 224742a390f48c64aac75095c7ac251077f07bdb
Committed by
Bin Meng
1 parent
41f4e4302f
Exists in
smarc_8mq_lf_v2020.04
and in
12 other branches
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_ */ |
arch/x86/lib/scu.c
... | ... | @@ -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 |