Commit 866225f394a9b3174d9ea39d2d19ac0d2c07a516

Authored by Michal Simek
1 parent 0f3604a2b3

arm64: xilinx: Move firmware functions from platform to driver

versal_pm_request() and invoke_smc() are almost the same. Only one
difference is that versal_pm_request is adding PM_SIP_SVC offset to api_id.
The patch is moving platform implementation to firmware driver code for
synchronization.

Signed-off-by: Michal Simek <michal.simek@xilinx.com>
Reviewed-by: Luca Ceresoli <luca@lucaceresoli.net>

Showing 7 changed files with 52 additions and 62 deletions Side-by-side Diff

arch/arm/mach-versal/cpu.c
... ... @@ -9,7 +9,6 @@
9 9 #include <asm/io.h>
10 10 #include <asm/arch/hardware.h>
11 11 #include <asm/arch/sys_proto.h>
12   -#include <zynqmp_firmware.h>
13 12  
14 13 DECLARE_GLOBAL_DATA_PTR;
15 14  
... ... @@ -108,29 +107,4 @@
108 107 return 0;
109 108 }
110 109 #endif
111   -
112   -int versal_pm_request(u32 api_id, u32 arg0, u32 arg1, u32 arg2,
113   - u32 arg3, u32 *ret_payload)
114   -{
115   - struct pt_regs regs;
116   -
117   - if (current_el() == 3)
118   - return 0;
119   -
120   - regs.regs[0] = PM_SIP_SVC | api_id;
121   - regs.regs[1] = ((u64)arg1 << 32) | arg0;
122   - regs.regs[2] = ((u64)arg3 << 32) | arg2;
123   -
124   - smc_call(&regs);
125   -
126   - if (ret_payload) {
127   - ret_payload[0] = (u32)regs.regs[0];
128   - ret_payload[1] = upper_32_bits(regs.regs[0]);
129   - ret_payload[2] = (u32)regs.regs[1];
130   - ret_payload[3] = upper_32_bits(regs.regs[1]);
131   - ret_payload[4] = (u32)regs.regs[2];
132   - }
133   -
134   - return regs.regs[0];
135   -}
arch/arm/mach-versal/include/mach/sys_proto.h
... ... @@ -12,7 +12,4 @@
12 12  
13 13 void tcm_init(u8 mode);
14 14 void mem_map_fill(void);
15   -
16   -int versal_pm_request(u32 api_id, u32 arg0, u32 arg1, u32 arg2,
17   - u32 arg3, u32 *ret_payload);
arch/arm/mach-zynqmp/cpu.c
... ... @@ -154,32 +154,6 @@
154 154 #define ZYNQMP_MMIO_READ 0xC2000014
155 155 #define ZYNQMP_MMIO_WRITE 0xC2000013
156 156  
157   -int __maybe_unused invoke_smc(u32 pm_api_id, u32 arg0, u32 arg1, u32 arg2,
158   - u32 arg3, u32 *ret_payload)
159   -{
160   - /*
161   - * Added SIP service call Function Identifier
162   - * Make sure to stay in x0 register
163   - */
164   - struct pt_regs regs;
165   -
166   - regs.regs[0] = pm_api_id;
167   - regs.regs[1] = ((u64)arg1 << 32) | arg0;
168   - regs.regs[2] = ((u64)arg3 << 32) | arg2;
169   -
170   - smc_call(&regs);
171   -
172   - if (ret_payload != NULL) {
173   - ret_payload[0] = (u32)regs.regs[0];
174   - ret_payload[1] = upper_32_bits(regs.regs[0]);
175   - ret_payload[2] = (u32)regs.regs[1];
176   - ret_payload[3] = upper_32_bits(regs.regs[1]);
177   - ret_payload[4] = (u32)regs.regs[2];
178   - }
179   -
180   - return regs.regs[0];
181   -}
182   -
183 157 static int zynqmp_mmio_rawwrite(const u32 address,
184 158 const u32 mask,
185 159 const u32 value)
186 160  
187 161  
188 162  
189 163  
190 164  
... ... @@ -211,28 +185,34 @@
211 185 {
212 186 if (IS_ENABLED(CONFIG_SPL_BUILD) || current_el() == 3)
213 187 return zynqmp_mmio_rawwrite(address, mask, value);
  188 +#if defined(CONFIG_ZYNQMP_FIRMWARE)
214 189 else
215 190 return invoke_smc(ZYNQMP_MMIO_WRITE, address, mask,
216 191 value, 0, NULL);
  192 +#endif
217 193  
218 194 return -EINVAL;
219 195 }
220 196  
221 197 int zynqmp_mmio_read(const u32 address, u32 *value)
222 198 {
223   - u32 ret_payload[PAYLOAD_ARG_CNT];
224   - u32 ret;
  199 + u32 ret = -EINVAL;
225 200  
226 201 if (!value)
227   - return -EINVAL;
  202 + return ret;
228 203  
229 204 if (IS_ENABLED(CONFIG_SPL_BUILD) || current_el() == 3) {
230 205 ret = zynqmp_mmio_rawread(address, value);
231   - } else {
  206 + }
  207 +#if defined(CONFIG_ZYNQMP_FIRMWARE)
  208 + else {
  209 + u32 ret_payload[PAYLOAD_ARG_CNT];
  210 +
232 211 ret = invoke_smc(ZYNQMP_MMIO_READ, address, 0, 0,
233 212 0, ret_payload);
234 213 *value = ret_payload[1];
235 214 }
  215 +#endif
236 216  
237 217 return ret;
238 218 }
arch/arm/mach-zynqmp/include/mach/sys_proto.h
... ... @@ -50,8 +50,6 @@
50 50  
51 51 int zynqmp_mmio_write(const u32 address, const u32 mask, const u32 value);
52 52 int zynqmp_mmio_read(const u32 address, u32 *value);
53   -int invoke_smc(u32 pm_api_id, u32 arg0, u32 arg1, u32 arg2, u32 arg3,
54   - u32 *ret_payload);
55 53  
56 54 void initialize_tcm(bool mode);
57 55 void mem_map_fill(void);
drivers/firmware/firmware-zynqmp.c
... ... @@ -7,10 +7,10 @@
7 7  
8 8 #include <common.h>
9 9 #include <dm.h>
  10 +#include <zynqmp_firmware.h>
10 11  
11 12 #if defined(CONFIG_ZYNQMP_IPI)
12 13 #include <mailbox.h>
13   -#include <zynqmp_firmware.h>
14 14 #include <asm/arch/sys_proto.h>
15 15  
16 16 #define PMUFW_PAYLOAD_ARG_CNT 8
... ... @@ -146,6 +146,42 @@
146 146 .probe = zynqmp_power_probe,
147 147 };
148 148 #endif
  149 +
  150 +int __maybe_unused invoke_smc(u32 pm_api_id, u32 arg0, u32 arg1, u32 arg2,
  151 + u32 arg3, u32 *ret_payload)
  152 +{
  153 + /*
  154 + * Added SIP service call Function Identifier
  155 + * Make sure to stay in x0 register
  156 + */
  157 + struct pt_regs regs;
  158 +
  159 + if (current_el() == 3)
  160 + return 0;
  161 +
  162 + regs.regs[0] = pm_api_id;
  163 + regs.regs[1] = ((u64)arg1 << 32) | arg0;
  164 + regs.regs[2] = ((u64)arg3 << 32) | arg2;
  165 +
  166 + smc_call(&regs);
  167 +
  168 + if (ret_payload) {
  169 + ret_payload[0] = (u32)regs.regs[0];
  170 + ret_payload[1] = upper_32_bits(regs.regs[0]);
  171 + ret_payload[2] = (u32)regs.regs[1];
  172 + ret_payload[3] = upper_32_bits(regs.regs[1]);
  173 + ret_payload[4] = (u32)regs.regs[2];
  174 + }
  175 +
  176 + return regs.regs[0];
  177 +}
  178 +
  179 +int __maybe_unused versal_pm_request(u32 api_id, u32 arg0, u32 arg1, u32 arg2,
  180 + u32 arg3, u32 *ret_payload)
  181 +{
  182 + return invoke_smc(PM_SIP_SVC | api_id, arg0, arg1, arg2, arg3,
  183 + ret_payload);
  184 +}
149 185  
150 186 static const struct udevice_id zynqmp_firmware_ids[] = {
151 187 { .compatible = "xlnx,zynqmp-firmware" },
drivers/fpga/versalpl.c
... ... @@ -8,6 +8,7 @@
8 8 #include <asm/arch/sys_proto.h>
9 9 #include <memalign.h>
10 10 #include <versalpl.h>
  11 +#include <zynqmp_firmware.h>
11 12  
12 13 static ulong versal_align_dma_buffer(ulong *buf, u32 len)
13 14 {
include/zynqmp_firmware.h
... ... @@ -81,6 +81,10 @@
81 81  
82 82 unsigned int zynqmp_firmware_version(void);
83 83 void zynqmp_pmufw_load_config_object(const void *cfg_obj, size_t size);
  84 +int invoke_smc(u32 pm_api_id, u32 arg0, u32 arg1, u32 arg2, u32 arg3,
  85 + u32 *ret_payload);
  86 +int versal_pm_request(u32 api_id, u32 arg0, u32 arg1, u32 arg2,
  87 + u32 arg3, u32 *ret_payload);
84 88  
85 89 #endif /* _ZYNQMP_FIRMWARE_H_ */