xref: /openbmc/linux/drivers/firmware/xilinx/zynqmp.c (revision 7ca4282ade77de53b6e9ffa2695566e5d35dab1e)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Xilinx Zynq MPSoC Firmware layer
4  *
5  *  Copyright (C) 2014-2020 Xilinx, Inc.
6  *
7  *  Michal Simek <michal.simek@xilinx.com>
8  *  Davorin Mista <davorin.mista@aggios.com>
9  *  Jolly Shah <jollys@xilinx.com>
10  *  Rajan Vaja <rajanv@xilinx.com>
11  */
12 
13 #include <linux/arm-smccc.h>
14 #include <linux/compiler.h>
15 #include <linux/device.h>
16 #include <linux/init.h>
17 #include <linux/mfd/core.h>
18 #include <linux/module.h>
19 #include <linux/of.h>
20 #include <linux/of_platform.h>
21 #include <linux/slab.h>
22 #include <linux/uaccess.h>
23 
24 #include <linux/firmware/xlnx-zynqmp.h>
25 #include "zynqmp-debug.h"
26 
27 static bool feature_check_enabled;
28 static u32 zynqmp_pm_features[PM_API_MAX];
29 
30 static const struct mfd_cell firmware_devs[] = {
31 	{
32 		.name = "zynqmp_power_controller",
33 	},
34 };
35 
36 /**
37  * zynqmp_pm_ret_code() - Convert PMU-FW error codes to Linux error codes
38  * @ret_status:		PMUFW return code
39  *
40  * Return: corresponding Linux error code
41  */
42 static int zynqmp_pm_ret_code(u32 ret_status)
43 {
44 	switch (ret_status) {
45 	case XST_PM_SUCCESS:
46 	case XST_PM_DOUBLE_REQ:
47 		return 0;
48 	case XST_PM_NO_FEATURE:
49 		return -ENOTSUPP;
50 	case XST_PM_NO_ACCESS:
51 		return -EACCES;
52 	case XST_PM_ABORT_SUSPEND:
53 		return -ECANCELED;
54 	case XST_PM_MULT_USER:
55 		return -EUSERS;
56 	case XST_PM_INTERNAL:
57 	case XST_PM_CONFLICT:
58 	case XST_PM_INVALID_NODE:
59 	default:
60 		return -EINVAL;
61 	}
62 }
63 
64 static noinline int do_fw_call_fail(u64 arg0, u64 arg1, u64 arg2,
65 				    u32 *ret_payload)
66 {
67 	return -ENODEV;
68 }
69 
70 /*
71  * PM function call wrapper
72  * Invoke do_fw_call_smc or do_fw_call_hvc, depending on the configuration
73  */
74 static int (*do_fw_call)(u64, u64, u64, u32 *ret_payload) = do_fw_call_fail;
75 
76 /**
77  * do_fw_call_smc() - Call system-level platform management layer (SMC)
78  * @arg0:		Argument 0 to SMC call
79  * @arg1:		Argument 1 to SMC call
80  * @arg2:		Argument 2 to SMC call
81  * @ret_payload:	Returned value array
82  *
83  * Invoke platform management function via SMC call (no hypervisor present).
84  *
85  * Return: Returns status, either success or error+reason
86  */
87 static noinline int do_fw_call_smc(u64 arg0, u64 arg1, u64 arg2,
88 				   u32 *ret_payload)
89 {
90 	struct arm_smccc_res res;
91 
92 	arm_smccc_smc(arg0, arg1, arg2, 0, 0, 0, 0, 0, &res);
93 
94 	if (ret_payload) {
95 		ret_payload[0] = lower_32_bits(res.a0);
96 		ret_payload[1] = upper_32_bits(res.a0);
97 		ret_payload[2] = lower_32_bits(res.a1);
98 		ret_payload[3] = upper_32_bits(res.a1);
99 	}
100 
101 	return zynqmp_pm_ret_code((enum pm_ret_status)res.a0);
102 }
103 
104 /**
105  * do_fw_call_hvc() - Call system-level platform management layer (HVC)
106  * @arg0:		Argument 0 to HVC call
107  * @arg1:		Argument 1 to HVC call
108  * @arg2:		Argument 2 to HVC call
109  * @ret_payload:	Returned value array
110  *
111  * Invoke platform management function via HVC
112  * HVC-based for communication through hypervisor
113  * (no direct communication with ATF).
114  *
115  * Return: Returns status, either success or error+reason
116  */
117 static noinline int do_fw_call_hvc(u64 arg0, u64 arg1, u64 arg2,
118 				   u32 *ret_payload)
119 {
120 	struct arm_smccc_res res;
121 
122 	arm_smccc_hvc(arg0, arg1, arg2, 0, 0, 0, 0, 0, &res);
123 
124 	if (ret_payload) {
125 		ret_payload[0] = lower_32_bits(res.a0);
126 		ret_payload[1] = upper_32_bits(res.a0);
127 		ret_payload[2] = lower_32_bits(res.a1);
128 		ret_payload[3] = upper_32_bits(res.a1);
129 	}
130 
131 	return zynqmp_pm_ret_code((enum pm_ret_status)res.a0);
132 }
133 
134 /**
135  * zynqmp_pm_feature() - Check weather given feature is supported or not
136  * @api_id:		API ID to check
137  *
138  * Return: Returns status, either success or error+reason
139  */
140 static int zynqmp_pm_feature(u32 api_id)
141 {
142 	int ret;
143 	u32 ret_payload[PAYLOAD_ARG_CNT];
144 	u64 smc_arg[2];
145 
146 	if (!feature_check_enabled)
147 		return 0;
148 
149 	/* Return value if feature is already checked */
150 	if (api_id > ARRAY_SIZE(zynqmp_pm_features))
151 		return PM_FEATURE_INVALID;
152 
153 	if (zynqmp_pm_features[api_id] != PM_FEATURE_UNCHECKED)
154 		return zynqmp_pm_features[api_id];
155 
156 	smc_arg[0] = PM_SIP_SVC | PM_FEATURE_CHECK;
157 	smc_arg[1] = api_id;
158 
159 	ret = do_fw_call(smc_arg[0], smc_arg[1], 0, ret_payload);
160 	if (ret) {
161 		zynqmp_pm_features[api_id] = PM_FEATURE_INVALID;
162 		return PM_FEATURE_INVALID;
163 	}
164 
165 	zynqmp_pm_features[api_id] = ret_payload[1];
166 
167 	return zynqmp_pm_features[api_id];
168 }
169 
170 /**
171  * zynqmp_pm_invoke_fn() - Invoke the system-level platform management layer
172  *			   caller function depending on the configuration
173  * @pm_api_id:		Requested PM-API call
174  * @arg0:		Argument 0 to requested PM-API call
175  * @arg1:		Argument 1 to requested PM-API call
176  * @arg2:		Argument 2 to requested PM-API call
177  * @arg3:		Argument 3 to requested PM-API call
178  * @ret_payload:	Returned value array
179  *
180  * Invoke platform management function for SMC or HVC call, depending on
181  * configuration.
182  * Following SMC Calling Convention (SMCCC) for SMC64:
183  * Pm Function Identifier,
184  * PM_SIP_SVC + PM_API_ID =
185  *	((SMC_TYPE_FAST << FUNCID_TYPE_SHIFT)
186  *	((SMC_64) << FUNCID_CC_SHIFT)
187  *	((SIP_START) << FUNCID_OEN_SHIFT)
188  *	((PM_API_ID) & FUNCID_NUM_MASK))
189  *
190  * PM_SIP_SVC	- Registered ZynqMP SIP Service Call.
191  * PM_API_ID	- Platform Management API ID.
192  *
193  * Return: Returns status, either success or error+reason
194  */
195 int zynqmp_pm_invoke_fn(u32 pm_api_id, u32 arg0, u32 arg1,
196 			u32 arg2, u32 arg3, u32 *ret_payload)
197 {
198 	/*
199 	 * Added SIP service call Function Identifier
200 	 * Make sure to stay in x0 register
201 	 */
202 	u64 smc_arg[4];
203 
204 	if (zynqmp_pm_feature(pm_api_id) == PM_FEATURE_INVALID)
205 		return -ENOTSUPP;
206 
207 	smc_arg[0] = PM_SIP_SVC | pm_api_id;
208 	smc_arg[1] = ((u64)arg1 << 32) | arg0;
209 	smc_arg[2] = ((u64)arg3 << 32) | arg2;
210 
211 	return do_fw_call(smc_arg[0], smc_arg[1], smc_arg[2], ret_payload);
212 }
213 
214 static u32 pm_api_version;
215 static u32 pm_tz_version;
216 
217 /**
218  * zynqmp_pm_get_api_version() - Get version number of PMU PM firmware
219  * @version:	Returned version value
220  *
221  * Return: Returns status, either success or error+reason
222  */
223 int zynqmp_pm_get_api_version(u32 *version)
224 {
225 	u32 ret_payload[PAYLOAD_ARG_CNT];
226 	int ret;
227 
228 	if (!version)
229 		return -EINVAL;
230 
231 	/* Check is PM API version already verified */
232 	if (pm_api_version > 0) {
233 		*version = pm_api_version;
234 		return 0;
235 	}
236 	ret = zynqmp_pm_invoke_fn(PM_GET_API_VERSION, 0, 0, 0, 0, ret_payload);
237 	*version = ret_payload[1];
238 
239 	return ret;
240 }
241 EXPORT_SYMBOL_GPL(zynqmp_pm_get_api_version);
242 
243 /**
244  * zynqmp_pm_get_chipid - Get silicon ID registers
245  * @idcode:     IDCODE register
246  * @version:    version register
247  *
248  * Return:      Returns the status of the operation and the idcode and version
249  *              registers in @idcode and @version.
250  */
251 int zynqmp_pm_get_chipid(u32 *idcode, u32 *version)
252 {
253 	u32 ret_payload[PAYLOAD_ARG_CNT];
254 	int ret;
255 
256 	if (!idcode || !version)
257 		return -EINVAL;
258 
259 	ret = zynqmp_pm_invoke_fn(PM_GET_CHIPID, 0, 0, 0, 0, ret_payload);
260 	*idcode = ret_payload[1];
261 	*version = ret_payload[2];
262 
263 	return ret;
264 }
265 EXPORT_SYMBOL_GPL(zynqmp_pm_get_chipid);
266 
267 /**
268  * zynqmp_pm_get_trustzone_version() - Get secure trustzone firmware version
269  * @version:	Returned version value
270  *
271  * Return: Returns status, either success or error+reason
272  */
273 static int zynqmp_pm_get_trustzone_version(u32 *version)
274 {
275 	u32 ret_payload[PAYLOAD_ARG_CNT];
276 	int ret;
277 
278 	if (!version)
279 		return -EINVAL;
280 
281 	/* Check is PM trustzone version already verified */
282 	if (pm_tz_version > 0) {
283 		*version = pm_tz_version;
284 		return 0;
285 	}
286 	ret = zynqmp_pm_invoke_fn(PM_GET_TRUSTZONE_VERSION, 0, 0,
287 				  0, 0, ret_payload);
288 	*version = ret_payload[1];
289 
290 	return ret;
291 }
292 
293 /**
294  * get_set_conduit_method() - Choose SMC or HVC based communication
295  * @np:		Pointer to the device_node structure
296  *
297  * Use SMC or HVC-based functions to communicate with EL2/EL3.
298  *
299  * Return: Returns 0 on success or error code
300  */
301 static int get_set_conduit_method(struct device_node *np)
302 {
303 	const char *method;
304 
305 	if (of_property_read_string(np, "method", &method)) {
306 		pr_warn("%s missing \"method\" property\n", __func__);
307 		return -ENXIO;
308 	}
309 
310 	if (!strcmp("hvc", method)) {
311 		do_fw_call = do_fw_call_hvc;
312 	} else if (!strcmp("smc", method)) {
313 		do_fw_call = do_fw_call_smc;
314 	} else {
315 		pr_warn("%s Invalid \"method\" property: %s\n",
316 			__func__, method);
317 		return -EINVAL;
318 	}
319 
320 	return 0;
321 }
322 
323 /**
324  * zynqmp_pm_query_data() - Get query data from firmware
325  * @qdata:	Variable to the zynqmp_pm_query_data structure
326  * @out:	Returned output value
327  *
328  * Return: Returns status, either success or error+reason
329  */
330 int zynqmp_pm_query_data(struct zynqmp_pm_query_data qdata, u32 *out)
331 {
332 	int ret;
333 
334 	ret = zynqmp_pm_invoke_fn(PM_QUERY_DATA, qdata.qid, qdata.arg1,
335 				  qdata.arg2, qdata.arg3, out);
336 
337 	/*
338 	 * For clock name query, all bytes in SMC response are clock name
339 	 * characters and return code is always success. For invalid clocks,
340 	 * clock name bytes would be zeros.
341 	 */
342 	return qdata.qid == PM_QID_CLOCK_GET_NAME ? 0 : ret;
343 }
344 EXPORT_SYMBOL_GPL(zynqmp_pm_query_data);
345 
346 /**
347  * zynqmp_pm_clock_enable() - Enable the clock for given id
348  * @clock_id:	ID of the clock to be enabled
349  *
350  * This function is used by master to enable the clock
351  * including peripherals and PLL clocks.
352  *
353  * Return: Returns status, either success or error+reason
354  */
355 int zynqmp_pm_clock_enable(u32 clock_id)
356 {
357 	return zynqmp_pm_invoke_fn(PM_CLOCK_ENABLE, clock_id, 0, 0, 0, NULL);
358 }
359 EXPORT_SYMBOL_GPL(zynqmp_pm_clock_enable);
360 
361 /**
362  * zynqmp_pm_clock_disable() - Disable the clock for given id
363  * @clock_id:	ID of the clock to be disable
364  *
365  * This function is used by master to disable the clock
366  * including peripherals and PLL clocks.
367  *
368  * Return: Returns status, either success or error+reason
369  */
370 int zynqmp_pm_clock_disable(u32 clock_id)
371 {
372 	return zynqmp_pm_invoke_fn(PM_CLOCK_DISABLE, clock_id, 0, 0, 0, NULL);
373 }
374 EXPORT_SYMBOL_GPL(zynqmp_pm_clock_disable);
375 
376 /**
377  * zynqmp_pm_clock_getstate() - Get the clock state for given id
378  * @clock_id:	ID of the clock to be queried
379  * @state:	1/0 (Enabled/Disabled)
380  *
381  * This function is used by master to get the state of clock
382  * including peripherals and PLL clocks.
383  *
384  * Return: Returns status, either success or error+reason
385  */
386 int zynqmp_pm_clock_getstate(u32 clock_id, u32 *state)
387 {
388 	u32 ret_payload[PAYLOAD_ARG_CNT];
389 	int ret;
390 
391 	ret = zynqmp_pm_invoke_fn(PM_CLOCK_GETSTATE, clock_id, 0,
392 				  0, 0, ret_payload);
393 	*state = ret_payload[1];
394 
395 	return ret;
396 }
397 EXPORT_SYMBOL_GPL(zynqmp_pm_clock_getstate);
398 
399 /**
400  * zynqmp_pm_clock_setdivider() - Set the clock divider for given id
401  * @clock_id:	ID of the clock
402  * @divider:	divider value
403  *
404  * This function is used by master to set divider for any clock
405  * to achieve desired rate.
406  *
407  * Return: Returns status, either success or error+reason
408  */
409 int zynqmp_pm_clock_setdivider(u32 clock_id, u32 divider)
410 {
411 	return zynqmp_pm_invoke_fn(PM_CLOCK_SETDIVIDER, clock_id, divider,
412 				   0, 0, NULL);
413 }
414 EXPORT_SYMBOL_GPL(zynqmp_pm_clock_setdivider);
415 
416 /**
417  * zynqmp_pm_clock_getdivider() - Get the clock divider for given id
418  * @clock_id:	ID of the clock
419  * @divider:	divider value
420  *
421  * This function is used by master to get divider values
422  * for any clock.
423  *
424  * Return: Returns status, either success or error+reason
425  */
426 int zynqmp_pm_clock_getdivider(u32 clock_id, u32 *divider)
427 {
428 	u32 ret_payload[PAYLOAD_ARG_CNT];
429 	int ret;
430 
431 	ret = zynqmp_pm_invoke_fn(PM_CLOCK_GETDIVIDER, clock_id, 0,
432 				  0, 0, ret_payload);
433 	*divider = ret_payload[1];
434 
435 	return ret;
436 }
437 EXPORT_SYMBOL_GPL(zynqmp_pm_clock_getdivider);
438 
439 /**
440  * zynqmp_pm_clock_setrate() - Set the clock rate for given id
441  * @clock_id:	ID of the clock
442  * @rate:	rate value in hz
443  *
444  * This function is used by master to set rate for any clock.
445  *
446  * Return: Returns status, either success or error+reason
447  */
448 int zynqmp_pm_clock_setrate(u32 clock_id, u64 rate)
449 {
450 	return zynqmp_pm_invoke_fn(PM_CLOCK_SETRATE, clock_id,
451 				   lower_32_bits(rate),
452 				   upper_32_bits(rate),
453 				   0, NULL);
454 }
455 EXPORT_SYMBOL_GPL(zynqmp_pm_clock_setrate);
456 
457 /**
458  * zynqmp_pm_clock_getrate() - Get the clock rate for given id
459  * @clock_id:	ID of the clock
460  * @rate:	rate value in hz
461  *
462  * This function is used by master to get rate
463  * for any clock.
464  *
465  * Return: Returns status, either success or error+reason
466  */
467 int zynqmp_pm_clock_getrate(u32 clock_id, u64 *rate)
468 {
469 	u32 ret_payload[PAYLOAD_ARG_CNT];
470 	int ret;
471 
472 	ret = zynqmp_pm_invoke_fn(PM_CLOCK_GETRATE, clock_id, 0,
473 				  0, 0, ret_payload);
474 	*rate = ((u64)ret_payload[2] << 32) | ret_payload[1];
475 
476 	return ret;
477 }
478 EXPORT_SYMBOL_GPL(zynqmp_pm_clock_getrate);
479 
480 /**
481  * zynqmp_pm_clock_setparent() - Set the clock parent for given id
482  * @clock_id:	ID of the clock
483  * @parent_id:	parent id
484  *
485  * This function is used by master to set parent for any clock.
486  *
487  * Return: Returns status, either success or error+reason
488  */
489 int zynqmp_pm_clock_setparent(u32 clock_id, u32 parent_id)
490 {
491 	return zynqmp_pm_invoke_fn(PM_CLOCK_SETPARENT, clock_id,
492 				   parent_id, 0, 0, NULL);
493 }
494 EXPORT_SYMBOL_GPL(zynqmp_pm_clock_setparent);
495 
496 /**
497  * zynqmp_pm_clock_getparent() - Get the clock parent for given id
498  * @clock_id:	ID of the clock
499  * @parent_id:	parent id
500  *
501  * This function is used by master to get parent index
502  * for any clock.
503  *
504  * Return: Returns status, either success or error+reason
505  */
506 int zynqmp_pm_clock_getparent(u32 clock_id, u32 *parent_id)
507 {
508 	u32 ret_payload[PAYLOAD_ARG_CNT];
509 	int ret;
510 
511 	ret = zynqmp_pm_invoke_fn(PM_CLOCK_GETPARENT, clock_id, 0,
512 				  0, 0, ret_payload);
513 	*parent_id = ret_payload[1];
514 
515 	return ret;
516 }
517 EXPORT_SYMBOL_GPL(zynqmp_pm_clock_getparent);
518 
519 /**
520  * zynqmp_pm_set_pll_frac_mode() - PM API for set PLL mode
521  *
522  * @clk_id:	PLL clock ID
523  * @mode:	PLL mode (PLL_MODE_FRAC/PLL_MODE_INT)
524  *
525  * This function sets PLL mode
526  *
527  * Return: Returns status, either success or error+reason
528  */
529 int zynqmp_pm_set_pll_frac_mode(u32 clk_id, u32 mode)
530 {
531 	return zynqmp_pm_invoke_fn(PM_IOCTL, 0, IOCTL_SET_PLL_FRAC_MODE,
532 				   clk_id, mode, NULL);
533 }
534 EXPORT_SYMBOL_GPL(zynqmp_pm_set_pll_frac_mode);
535 
536 /**
537  * zynqmp_pm_get_pll_frac_mode() - PM API for get PLL mode
538  *
539  * @clk_id:	PLL clock ID
540  * @mode:	PLL mode
541  *
542  * This function return current PLL mode
543  *
544  * Return: Returns status, either success or error+reason
545  */
546 int zynqmp_pm_get_pll_frac_mode(u32 clk_id, u32 *mode)
547 {
548 	return zynqmp_pm_invoke_fn(PM_IOCTL, 0, IOCTL_GET_PLL_FRAC_MODE,
549 				   clk_id, 0, mode);
550 }
551 EXPORT_SYMBOL_GPL(zynqmp_pm_get_pll_frac_mode);
552 
553 /**
554  * zynqmp_pm_set_pll_frac_data() - PM API for setting pll fraction data
555  *
556  * @clk_id:	PLL clock ID
557  * @data:	fraction data
558  *
559  * This function sets fraction data.
560  * It is valid for fraction mode only.
561  *
562  * Return: Returns status, either success or error+reason
563  */
564 int zynqmp_pm_set_pll_frac_data(u32 clk_id, u32 data)
565 {
566 	return zynqmp_pm_invoke_fn(PM_IOCTL, 0, IOCTL_SET_PLL_FRAC_DATA,
567 				   clk_id, data, NULL);
568 }
569 EXPORT_SYMBOL_GPL(zynqmp_pm_set_pll_frac_data);
570 
571 /**
572  * zynqmp_pm_get_pll_frac_data() - PM API for getting pll fraction data
573  *
574  * @clk_id:	PLL clock ID
575  * @data:	fraction data
576  *
577  * This function returns fraction data value.
578  *
579  * Return: Returns status, either success or error+reason
580  */
581 int zynqmp_pm_get_pll_frac_data(u32 clk_id, u32 *data)
582 {
583 	return zynqmp_pm_invoke_fn(PM_IOCTL, 0, IOCTL_GET_PLL_FRAC_DATA,
584 				   clk_id, 0, data);
585 }
586 EXPORT_SYMBOL_GPL(zynqmp_pm_get_pll_frac_data);
587 
588 /**
589  * zynqmp_pm_set_sd_tapdelay() -  Set tap delay for the SD device
590  *
591  * @node_id	Node ID of the device
592  * @type	Type of tap delay to set (input/output)
593  * @value	Value to set fot the tap delay
594  *
595  * This function sets input/output tap delay for the SD device.
596  *
597  * @return	Returns status, either success or error+reason
598  */
599 int zynqmp_pm_set_sd_tapdelay(u32 node_id, u32 type, u32 value)
600 {
601 	return zynqmp_pm_invoke_fn(PM_IOCTL, node_id, IOCTL_SET_SD_TAPDELAY,
602 				   type, value, NULL);
603 }
604 EXPORT_SYMBOL_GPL(zynqmp_pm_set_sd_tapdelay);
605 
606 /**
607  * zynqmp_pm_sd_dll_reset() - Reset DLL logic
608  *
609  * @node_id	Node ID of the device
610  * @type	Reset type
611  *
612  * This function resets DLL logic for the SD device.
613  *
614  * @return	Returns status, either success or error+reason
615  */
616 int zynqmp_pm_sd_dll_reset(u32 node_id, u32 type)
617 {
618 	return zynqmp_pm_invoke_fn(PM_IOCTL, node_id, IOCTL_SET_SD_TAPDELAY,
619 				   type, 0, NULL);
620 }
621 EXPORT_SYMBOL_GPL(zynqmp_pm_sd_dll_reset);
622 
623 /**
624  * zynqmp_pm_write_ggs() - PM API for writing global general storage (ggs)
625  * @index	GGS register index
626  * @value	Register value to be written
627  *
628  * This function writes value to GGS register.
629  *
630  * @return      Returns status, either success or error+reason
631  */
632 int zynqmp_pm_write_ggs(u32 index, u32 value)
633 {
634 	return zynqmp_pm_invoke_fn(PM_IOCTL, 0, IOCTL_WRITE_GGS,
635 				   index, value, NULL);
636 }
637 EXPORT_SYMBOL_GPL(zynqmp_pm_write_ggs);
638 
639 /**
640  * zynqmp_pm_write_ggs() - PM API for reading global general storage (ggs)
641  * @index	GGS register index
642  * @value	Register value to be written
643  *
644  * This function returns GGS register value.
645  *
646  * @return      Returns status, either success or error+reason
647  */
648 int zynqmp_pm_read_ggs(u32 index, u32 *value)
649 {
650 	return zynqmp_pm_invoke_fn(PM_IOCTL, 0, IOCTL_READ_GGS,
651 				   index, 0, value);
652 }
653 EXPORT_SYMBOL_GPL(zynqmp_pm_read_ggs);
654 
655 /**
656  * zynqmp_pm_write_pggs() - PM API for writing persistent global general
657  *			     storage (pggs)
658  * @index	PGGS register index
659  * @value	Register value to be written
660  *
661  * This function writes value to PGGS register.
662  *
663  * @return      Returns status, either success or error+reason
664  */
665 int zynqmp_pm_write_pggs(u32 index, u32 value)
666 {
667 	return zynqmp_pm_invoke_fn(PM_IOCTL, 0, IOCTL_WRITE_PGGS, index, value,
668 				   NULL);
669 }
670 EXPORT_SYMBOL_GPL(zynqmp_pm_write_pggs);
671 
672 /**
673  * zynqmp_pm_write_pggs() - PM API for reading persistent global general
674  *			     storage (pggs)
675  * @index	PGGS register index
676  * @value	Register value to be written
677  *
678  * This function returns PGGS register value.
679  *
680  * @return      Returns status, either success or error+reason
681  */
682 int zynqmp_pm_read_pggs(u32 index, u32 *value)
683 {
684 	return zynqmp_pm_invoke_fn(PM_IOCTL, 0, IOCTL_READ_PGGS, index, 0,
685 				   value);
686 }
687 EXPORT_SYMBOL_GPL(zynqmp_pm_read_pggs);
688 
689 /**
690  * zynqmp_pm_set_boot_health_status() - PM API for setting healthy boot status
691  * @value	Status value to be written
692  *
693  * This function sets healthy bit value to indicate boot health status
694  * to firmware.
695  *
696  * @return      Returns status, either success or error+reason
697  */
698 int zynqmp_pm_set_boot_health_status(u32 value)
699 {
700 	return zynqmp_pm_invoke_fn(PM_IOCTL, 0, IOCTL_SET_BOOT_HEALTH_STATUS,
701 				   value, 0, NULL);
702 }
703 
704 /**
705  * zynqmp_pm_reset_assert - Request setting of reset (1 - assert, 0 - release)
706  * @reset:		Reset to be configured
707  * @assert_flag:	Flag stating should reset be asserted (1) or
708  *			released (0)
709  *
710  * Return: Returns status, either success or error+reason
711  */
712 int zynqmp_pm_reset_assert(const enum zynqmp_pm_reset reset,
713 			   const enum zynqmp_pm_reset_action assert_flag)
714 {
715 	return zynqmp_pm_invoke_fn(PM_RESET_ASSERT, reset, assert_flag,
716 				   0, 0, NULL);
717 }
718 EXPORT_SYMBOL_GPL(zynqmp_pm_reset_assert);
719 
720 /**
721  * zynqmp_pm_reset_get_status - Get status of the reset
722  * @reset:      Reset whose status should be returned
723  * @status:     Returned status
724  *
725  * Return: Returns status, either success or error+reason
726  */
727 int zynqmp_pm_reset_get_status(const enum zynqmp_pm_reset reset, u32 *status)
728 {
729 	u32 ret_payload[PAYLOAD_ARG_CNT];
730 	int ret;
731 
732 	if (!status)
733 		return -EINVAL;
734 
735 	ret = zynqmp_pm_invoke_fn(PM_RESET_GET_STATUS, reset, 0,
736 				  0, 0, ret_payload);
737 	*status = ret_payload[1];
738 
739 	return ret;
740 }
741 EXPORT_SYMBOL_GPL(zynqmp_pm_reset_get_status);
742 
743 /**
744  * zynqmp_pm_fpga_load - Perform the fpga load
745  * @address:	Address to write to
746  * @size:	pl bitstream size
747  * @flags:	Bitstream type
748  *	-XILINX_ZYNQMP_PM_FPGA_FULL:  FPGA full reconfiguration
749  *	-XILINX_ZYNQMP_PM_FPGA_PARTIAL: FPGA partial reconfiguration
750  *
751  * This function provides access to pmufw. To transfer
752  * the required bitstream into PL.
753  *
754  * Return: Returns status, either success or error+reason
755  */
756 int zynqmp_pm_fpga_load(const u64 address, const u32 size, const u32 flags)
757 {
758 	return zynqmp_pm_invoke_fn(PM_FPGA_LOAD, lower_32_bits(address),
759 				   upper_32_bits(address), size, flags, NULL);
760 }
761 EXPORT_SYMBOL_GPL(zynqmp_pm_fpga_load);
762 
763 /**
764  * zynqmp_pm_fpga_get_status - Read value from PCAP status register
765  * @value: Value to read
766  *
767  * This function provides access to the pmufw to get the PCAP
768  * status
769  *
770  * Return: Returns status, either success or error+reason
771  */
772 int zynqmp_pm_fpga_get_status(u32 *value)
773 {
774 	u32 ret_payload[PAYLOAD_ARG_CNT];
775 	int ret;
776 
777 	if (!value)
778 		return -EINVAL;
779 
780 	ret = zynqmp_pm_invoke_fn(PM_FPGA_GET_STATUS, 0, 0, 0, 0, ret_payload);
781 	*value = ret_payload[1];
782 
783 	return ret;
784 }
785 EXPORT_SYMBOL_GPL(zynqmp_pm_fpga_get_status);
786 
787 /**
788  * zynqmp_pm_init_finalize() - PM call to inform firmware that the caller
789  *			       master has initialized its own power management
790  *
791  * This API function is to be used for notify the power management controller
792  * about the completed power management initialization.
793  *
794  * Return: Returns status, either success or error+reason
795  */
796 int zynqmp_pm_init_finalize(void)
797 {
798 	return zynqmp_pm_invoke_fn(PM_PM_INIT_FINALIZE, 0, 0, 0, 0, NULL);
799 }
800 EXPORT_SYMBOL_GPL(zynqmp_pm_init_finalize);
801 
802 /**
803  * zynqmp_pm_set_suspend_mode()	- Set system suspend mode
804  * @mode:	Mode to set for system suspend
805  *
806  * This API function is used to set mode of system suspend.
807  *
808  * Return: Returns status, either success or error+reason
809  */
810 int zynqmp_pm_set_suspend_mode(u32 mode)
811 {
812 	return zynqmp_pm_invoke_fn(PM_SET_SUSPEND_MODE, mode, 0, 0, 0, NULL);
813 }
814 EXPORT_SYMBOL_GPL(zynqmp_pm_set_suspend_mode);
815 
816 /**
817  * zynqmp_pm_request_node() - Request a node with specific capabilities
818  * @node:		Node ID of the slave
819  * @capabilities:	Requested capabilities of the slave
820  * @qos:		Quality of service (not supported)
821  * @ack:		Flag to specify whether acknowledge is requested
822  *
823  * This function is used by master to request particular node from firmware.
824  * Every master must request node before using it.
825  *
826  * Return: Returns status, either success or error+reason
827  */
828 int zynqmp_pm_request_node(const u32 node, const u32 capabilities,
829 			   const u32 qos, const enum zynqmp_pm_request_ack ack)
830 {
831 	return zynqmp_pm_invoke_fn(PM_REQUEST_NODE, node, capabilities,
832 				   qos, ack, NULL);
833 }
834 EXPORT_SYMBOL_GPL(zynqmp_pm_request_node);
835 
836 /**
837  * zynqmp_pm_release_node() - Release a node
838  * @node:	Node ID of the slave
839  *
840  * This function is used by master to inform firmware that master
841  * has released node. Once released, master must not use that node
842  * without re-request.
843  *
844  * Return: Returns status, either success or error+reason
845  */
846 int zynqmp_pm_release_node(const u32 node)
847 {
848 	return zynqmp_pm_invoke_fn(PM_RELEASE_NODE, node, 0, 0, 0, NULL);
849 }
850 EXPORT_SYMBOL_GPL(zynqmp_pm_release_node);
851 
852 /**
853  * zynqmp_pm_set_requirement() - PM call to set requirement for PM slaves
854  * @node:		Node ID of the slave
855  * @capabilities:	Requested capabilities of the slave
856  * @qos:		Quality of service (not supported)
857  * @ack:		Flag to specify whether acknowledge is requested
858  *
859  * This API function is to be used for slaves a PU already has requested
860  * to change its capabilities.
861  *
862  * Return: Returns status, either success or error+reason
863  */
864 int zynqmp_pm_set_requirement(const u32 node, const u32 capabilities,
865 			      const u32 qos,
866 			      const enum zynqmp_pm_request_ack ack)
867 {
868 	return zynqmp_pm_invoke_fn(PM_SET_REQUIREMENT, node, capabilities,
869 				   qos, ack, NULL);
870 }
871 EXPORT_SYMBOL_GPL(zynqmp_pm_set_requirement);
872 
873 /**
874  * zynqmp_pm_aes - Access AES hardware to encrypt/decrypt the data using
875  * AES-GCM core.
876  * @address:	Address of the AesParams structure.
877  * @out:	Returned output value
878  *
879  * Return:	Returns status, either success or error code.
880  */
881 int zynqmp_pm_aes_engine(const u64 address, u32 *out)
882 {
883 	u32 ret_payload[PAYLOAD_ARG_CNT];
884 	int ret;
885 
886 	if (!out)
887 		return -EINVAL;
888 
889 	ret = zynqmp_pm_invoke_fn(PM_SECURE_AES, upper_32_bits(address),
890 				  lower_32_bits(address),
891 				  0, 0, ret_payload);
892 	*out = ret_payload[1];
893 
894 	return ret;
895 }
896 EXPORT_SYMBOL_GPL(zynqmp_pm_aes_engine);
897 
898 /**
899  * zynqmp_pm_system_shutdown - PM call to request a system shutdown or restart
900  * @type:	Shutdown or restart? 0 for shutdown, 1 for restart
901  * @subtype:	Specifies which system should be restarted or shut down
902  *
903  * Return:	Returns status, either success or error+reason
904  */
905 int zynqmp_pm_system_shutdown(const u32 type, const u32 subtype)
906 {
907 	return zynqmp_pm_invoke_fn(PM_SYSTEM_SHUTDOWN, type, subtype,
908 				   0, 0, NULL);
909 }
910 
911 /**
912  * struct zynqmp_pm_shutdown_scope - Struct for shutdown scope
913  * @subtype:	Shutdown subtype
914  * @name:	Matching string for scope argument
915  *
916  * This struct encapsulates mapping between shutdown scope ID and string.
917  */
918 struct zynqmp_pm_shutdown_scope {
919 	const enum zynqmp_pm_shutdown_subtype subtype;
920 	const char *name;
921 };
922 
923 static struct zynqmp_pm_shutdown_scope shutdown_scopes[] = {
924 	[ZYNQMP_PM_SHUTDOWN_SUBTYPE_SUBSYSTEM] = {
925 		.subtype = ZYNQMP_PM_SHUTDOWN_SUBTYPE_SUBSYSTEM,
926 		.name = "subsystem",
927 	},
928 	[ZYNQMP_PM_SHUTDOWN_SUBTYPE_PS_ONLY] = {
929 		.subtype = ZYNQMP_PM_SHUTDOWN_SUBTYPE_PS_ONLY,
930 		.name = "ps_only",
931 	},
932 	[ZYNQMP_PM_SHUTDOWN_SUBTYPE_SYSTEM] = {
933 		.subtype = ZYNQMP_PM_SHUTDOWN_SUBTYPE_SYSTEM,
934 		.name = "system",
935 	},
936 };
937 
938 static struct zynqmp_pm_shutdown_scope *selected_scope =
939 		&shutdown_scopes[ZYNQMP_PM_SHUTDOWN_SUBTYPE_SYSTEM];
940 
941 /**
942  * zynqmp_pm_is_shutdown_scope_valid - Check if shutdown scope string is valid
943  * @scope_string:	Shutdown scope string
944  *
945  * Return:		Return pointer to matching shutdown scope struct from
946  *			array of available options in system if string is valid,
947  *			otherwise returns NULL.
948  */
949 static struct zynqmp_pm_shutdown_scope*
950 		zynqmp_pm_is_shutdown_scope_valid(const char *scope_string)
951 {
952 	int count;
953 
954 	for (count = 0; count < ARRAY_SIZE(shutdown_scopes); count++)
955 		if (sysfs_streq(scope_string, shutdown_scopes[count].name))
956 			return &shutdown_scopes[count];
957 
958 	return NULL;
959 }
960 
961 static ssize_t shutdown_scope_show(struct device *device,
962 				   struct device_attribute *attr,
963 				   char *buf)
964 {
965 	int i;
966 
967 	for (i = 0; i < ARRAY_SIZE(shutdown_scopes); i++) {
968 		if (&shutdown_scopes[i] == selected_scope) {
969 			strcat(buf, "[");
970 			strcat(buf, shutdown_scopes[i].name);
971 			strcat(buf, "]");
972 		} else {
973 			strcat(buf, shutdown_scopes[i].name);
974 		}
975 		strcat(buf, " ");
976 	}
977 	strcat(buf, "\n");
978 
979 	return strlen(buf);
980 }
981 
982 static ssize_t shutdown_scope_store(struct device *device,
983 				    struct device_attribute *attr,
984 				    const char *buf, size_t count)
985 {
986 	int ret;
987 	struct zynqmp_pm_shutdown_scope *scope;
988 
989 	scope = zynqmp_pm_is_shutdown_scope_valid(buf);
990 	if (!scope)
991 		return -EINVAL;
992 
993 	ret = zynqmp_pm_system_shutdown(ZYNQMP_PM_SHUTDOWN_TYPE_SETSCOPE_ONLY,
994 					scope->subtype);
995 	if (ret) {
996 		pr_err("unable to set shutdown scope %s\n", buf);
997 		return ret;
998 	}
999 
1000 	selected_scope = scope;
1001 
1002 	return count;
1003 }
1004 
1005 static DEVICE_ATTR_RW(shutdown_scope);
1006 
1007 static ssize_t health_status_store(struct device *device,
1008 				   struct device_attribute *attr,
1009 				   const char *buf, size_t count)
1010 {
1011 	int ret;
1012 	unsigned int value;
1013 
1014 	ret = kstrtouint(buf, 10, &value);
1015 	if (ret)
1016 		return ret;
1017 
1018 	ret = zynqmp_pm_set_boot_health_status(value);
1019 	if (ret) {
1020 		dev_err(device, "unable to set healthy bit value to %u\n",
1021 			value);
1022 		return ret;
1023 	}
1024 
1025 	return count;
1026 }
1027 
1028 static DEVICE_ATTR_WO(health_status);
1029 
1030 static ssize_t ggs_show(struct device *device,
1031 			struct device_attribute *attr,
1032 			char *buf,
1033 			u32 reg)
1034 {
1035 	int ret;
1036 	u32 ret_payload[PAYLOAD_ARG_CNT];
1037 
1038 	ret = zynqmp_pm_read_ggs(reg, ret_payload);
1039 	if (ret)
1040 		return ret;
1041 
1042 	return sprintf(buf, "0x%x\n", ret_payload[1]);
1043 }
1044 
1045 static ssize_t ggs_store(struct device *device,
1046 			 struct device_attribute *attr,
1047 			 const char *buf, size_t count,
1048 			 u32 reg)
1049 {
1050 	long value;
1051 	int ret;
1052 
1053 	if (reg >= GSS_NUM_REGS)
1054 		return -EINVAL;
1055 
1056 	ret = kstrtol(buf, 16, &value);
1057 	if (ret) {
1058 		count = -EFAULT;
1059 		goto err;
1060 	}
1061 
1062 	ret = zynqmp_pm_write_ggs(reg, value);
1063 	if (ret)
1064 		count = -EFAULT;
1065 err:
1066 	return count;
1067 }
1068 
1069 /* GGS register show functions */
1070 #define GGS0_SHOW(N)						\
1071 	ssize_t ggs##N##_show(struct device *device,		\
1072 			      struct device_attribute *attr,	\
1073 			      char *buf)			\
1074 	{							\
1075 		return ggs_show(device, attr, buf, N);		\
1076 	}
1077 
1078 static GGS0_SHOW(0);
1079 static GGS0_SHOW(1);
1080 static GGS0_SHOW(2);
1081 static GGS0_SHOW(3);
1082 
1083 /* GGS register store function */
1084 #define GGS0_STORE(N)						\
1085 	ssize_t ggs##N##_store(struct device *device,		\
1086 			       struct device_attribute *attr,	\
1087 			       const char *buf,			\
1088 			       size_t count)			\
1089 	{							\
1090 		return ggs_store(device, attr, buf, count, N);	\
1091 	}
1092 
1093 static GGS0_STORE(0);
1094 static GGS0_STORE(1);
1095 static GGS0_STORE(2);
1096 static GGS0_STORE(3);
1097 
1098 static ssize_t pggs_show(struct device *device,
1099 			 struct device_attribute *attr,
1100 			 char *buf,
1101 			 u32 reg)
1102 {
1103 	int ret;
1104 	u32 ret_payload[PAYLOAD_ARG_CNT];
1105 
1106 	ret = zynqmp_pm_read_pggs(reg, ret_payload);
1107 	if (ret)
1108 		return ret;
1109 
1110 	return sprintf(buf, "0x%x\n", ret_payload[1]);
1111 }
1112 
1113 static ssize_t pggs_store(struct device *device,
1114 			  struct device_attribute *attr,
1115 			  const char *buf, size_t count,
1116 			  u32 reg)
1117 {
1118 	long value;
1119 	int ret;
1120 
1121 	if (reg >= GSS_NUM_REGS)
1122 		return -EINVAL;
1123 
1124 	ret = kstrtol(buf, 16, &value);
1125 	if (ret) {
1126 		count = -EFAULT;
1127 		goto err;
1128 	}
1129 
1130 	ret = zynqmp_pm_write_pggs(reg, value);
1131 	if (ret)
1132 		count = -EFAULT;
1133 
1134 err:
1135 	return count;
1136 }
1137 
1138 #define PGGS0_SHOW(N)						\
1139 	ssize_t pggs##N##_show(struct device *device,		\
1140 			       struct device_attribute *attr,	\
1141 			       char *buf)			\
1142 	{							\
1143 		return pggs_show(device, attr, buf, N);		\
1144 	}
1145 
1146 #define PGGS0_STORE(N)						\
1147 	ssize_t pggs##N##_store(struct device *device,		\
1148 				struct device_attribute *attr,	\
1149 				const char *buf,		\
1150 				size_t count)			\
1151 	{							\
1152 		return pggs_store(device, attr, buf, count, N);	\
1153 	}
1154 
1155 /* PGGS register show functions */
1156 static PGGS0_SHOW(0);
1157 static PGGS0_SHOW(1);
1158 static PGGS0_SHOW(2);
1159 static PGGS0_SHOW(3);
1160 
1161 /* PGGS register store functions */
1162 static PGGS0_STORE(0);
1163 static PGGS0_STORE(1);
1164 static PGGS0_STORE(2);
1165 static PGGS0_STORE(3);
1166 
1167 /* GGS register attributes */
1168 static DEVICE_ATTR_RW(ggs0);
1169 static DEVICE_ATTR_RW(ggs1);
1170 static DEVICE_ATTR_RW(ggs2);
1171 static DEVICE_ATTR_RW(ggs3);
1172 
1173 /* PGGS register attributes */
1174 static DEVICE_ATTR_RW(pggs0);
1175 static DEVICE_ATTR_RW(pggs1);
1176 static DEVICE_ATTR_RW(pggs2);
1177 static DEVICE_ATTR_RW(pggs3);
1178 
1179 static struct attribute *zynqmp_firmware_attrs[] = {
1180 	&dev_attr_ggs0.attr,
1181 	&dev_attr_ggs1.attr,
1182 	&dev_attr_ggs2.attr,
1183 	&dev_attr_ggs3.attr,
1184 	&dev_attr_pggs0.attr,
1185 	&dev_attr_pggs1.attr,
1186 	&dev_attr_pggs2.attr,
1187 	&dev_attr_pggs3.attr,
1188 	&dev_attr_shutdown_scope.attr,
1189 	&dev_attr_health_status.attr,
1190 	NULL,
1191 };
1192 
1193 ATTRIBUTE_GROUPS(zynqmp_firmware);
1194 
1195 static int zynqmp_firmware_probe(struct platform_device *pdev)
1196 {
1197 	struct device *dev = &pdev->dev;
1198 	struct device_node *np;
1199 	int ret;
1200 
1201 	np = of_find_compatible_node(NULL, NULL, "xlnx,zynqmp");
1202 	if (!np) {
1203 		np = of_find_compatible_node(NULL, NULL, "xlnx,versal");
1204 		if (!np)
1205 			return 0;
1206 
1207 		feature_check_enabled = true;
1208 	}
1209 	of_node_put(np);
1210 
1211 	ret = get_set_conduit_method(dev->of_node);
1212 	if (ret)
1213 		return ret;
1214 
1215 	/* Check PM API version number */
1216 	zynqmp_pm_get_api_version(&pm_api_version);
1217 	if (pm_api_version < ZYNQMP_PM_VERSION) {
1218 		panic("%s Platform Management API version error. Expected: v%d.%d - Found: v%d.%d\n",
1219 		      __func__,
1220 		      ZYNQMP_PM_VERSION_MAJOR, ZYNQMP_PM_VERSION_MINOR,
1221 		      pm_api_version >> 16, pm_api_version & 0xFFFF);
1222 	}
1223 
1224 	pr_info("%s Platform Management API v%d.%d\n", __func__,
1225 		pm_api_version >> 16, pm_api_version & 0xFFFF);
1226 
1227 	/* Check trustzone version number */
1228 	ret = zynqmp_pm_get_trustzone_version(&pm_tz_version);
1229 	if (ret)
1230 		panic("Legacy trustzone found without version support\n");
1231 
1232 	if (pm_tz_version < ZYNQMP_TZ_VERSION)
1233 		panic("%s Trustzone version error. Expected: v%d.%d - Found: v%d.%d\n",
1234 		      __func__,
1235 		      ZYNQMP_TZ_VERSION_MAJOR, ZYNQMP_TZ_VERSION_MINOR,
1236 		      pm_tz_version >> 16, pm_tz_version & 0xFFFF);
1237 
1238 	pr_info("%s Trustzone version v%d.%d\n", __func__,
1239 		pm_tz_version >> 16, pm_tz_version & 0xFFFF);
1240 
1241 	ret = mfd_add_devices(&pdev->dev, PLATFORM_DEVID_NONE, firmware_devs,
1242 			      ARRAY_SIZE(firmware_devs), NULL, 0, NULL);
1243 	if (ret) {
1244 		dev_err(&pdev->dev, "failed to add MFD devices %d\n", ret);
1245 		return ret;
1246 	}
1247 
1248 	zynqmp_pm_api_debugfs_init();
1249 
1250 	return of_platform_populate(dev->of_node, NULL, NULL, dev);
1251 }
1252 
1253 static int zynqmp_firmware_remove(struct platform_device *pdev)
1254 {
1255 	mfd_remove_devices(&pdev->dev);
1256 	zynqmp_pm_api_debugfs_exit();
1257 
1258 	return 0;
1259 }
1260 
1261 static const struct of_device_id zynqmp_firmware_of_match[] = {
1262 	{.compatible = "xlnx,zynqmp-firmware"},
1263 	{.compatible = "xlnx,versal-firmware"},
1264 	{},
1265 };
1266 MODULE_DEVICE_TABLE(of, zynqmp_firmware_of_match);
1267 
1268 static struct platform_driver zynqmp_firmware_driver = {
1269 	.driver = {
1270 		.name = "zynqmp_firmware",
1271 		.of_match_table = zynqmp_firmware_of_match,
1272 		.dev_groups = zynqmp_firmware_groups,
1273 	},
1274 	.probe = zynqmp_firmware_probe,
1275 	.remove = zynqmp_firmware_remove,
1276 };
1277 module_platform_driver(zynqmp_firmware_driver);
1278