File Index
Files and directories
Sign in
FILE

zynqmp.c

File preview with syntax highlighting.

linux-6.19.14/drivers/firmware/xilinx/zynqmp.c C
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * Xilinx Zynq MPSoC Firmware layer
   4 *
   5 *  Copyright (C) 2014-2022 Xilinx, Inc.
   6 *  Copyright (C) 2022 - 2025 Advanced Micro Devices, Inc.
   7 *
   8 *  Michal Simek <michal.simek@amd.com>
   9 *  Davorin Mista <davorin.mista@aggios.com>
  10 *  Jolly Shah <jollys@xilinx.com>
  11 *  Rajan Vaja <rajanv@xilinx.com>
  12 */
  13
  14#include <linux/arm-smccc.h>
  15#include <linux/compiler.h>
  16#include <linux/device.h>
  17#include <linux/init.h>
  18#include <linux/mfd/core.h>
  19#include <linux/module.h>
  20#include <linux/of.h>
  21#include <linux/of_platform.h>
  22#include <linux/platform_device.h>
  23#include <linux/pm_domain.h>
  24#include <linux/slab.h>
  25#include <linux/uaccess.h>
  26#include <linux/hashtable.h>
  27
  28#include <linux/firmware/xlnx-zynqmp.h>
  29#include <linux/firmware/xlnx-event-manager.h>
  30#include "zynqmp-debug.h"
  31
  32/* Max HashMap Order for PM API feature check (1<<7 = 128) */
  33#define PM_API_FEATURE_CHECK_MAX_ORDER  7
  34
  35/* CRL registers and bitfields */
  36#define CRL_APB_BASE			0xFF5E0000U
  37/* BOOT_PIN_CTRL- Used to control the mode pins after boot */
  38#define CRL_APB_BOOT_PIN_CTRL		(CRL_APB_BASE + (0x250U))
  39/* BOOT_PIN_CTRL_MASK- out_val[11:8], out_en[3:0] */
  40#define CRL_APB_BOOTPIN_CTRL_MASK	0xF0FU
  41
  42/* IOCTL/QUERY feature payload size */
  43#define FEATURE_PAYLOAD_SIZE		2
  44
  45static bool feature_check_enabled;
  46static DEFINE_HASHTABLE(pm_api_features_map, PM_API_FEATURE_CHECK_MAX_ORDER);
  47static u32 ioctl_features[FEATURE_PAYLOAD_SIZE];
  48static u32 query_features[FEATURE_PAYLOAD_SIZE];
  49
  50static u32 sip_svc_version;
  51static struct platform_device *em_dev;
  52
  53/**
  54 * struct zynqmp_devinfo - Structure for Zynqmp device instance
  55 * @dev:		Device Pointer
  56 * @feature_conf_id:	Feature conf id
  57 */
  58struct zynqmp_devinfo {
  59	struct device *dev;
  60	u32 feature_conf_id;
  61};
  62
  63/**
  64 * struct pm_api_feature_data - PM API Feature data
  65 * @pm_api_id:		PM API Id, used as key to index into hashmap
  66 * @feature_status:	status of PM API feature: valid, invalid
  67 * @hentry:		hlist_node that hooks this entry into hashtable
  68 */
  69struct pm_api_feature_data {
  70	u32 pm_api_id;
  71	int feature_status;
  72	struct hlist_node hentry;
  73};
  74
  75struct platform_fw_data {
  76	/*
  77	 * Family code for platform.
  78	 */
  79	const u32 family_code;
  80};
  81
  82static struct platform_fw_data *active_platform_fw_data;
  83
  84static const struct mfd_cell firmware_devs[] = {
  85	{
  86		.name = "zynqmp_power_controller",
  87	},
  88};
  89
  90/**
  91 * zynqmp_pm_ret_code() - Convert PMU-FW error codes to Linux error codes
  92 * @ret_status:		PMUFW return code
  93 *
  94 * Return: corresponding Linux error code
  95 */
  96static int zynqmp_pm_ret_code(u32 ret_status)
  97{
  98	switch (ret_status) {
  99	case XST_PM_SUCCESS:
 100	case XST_PM_DOUBLE_REQ:
 101		return 0;
 102	case XST_PM_NO_FEATURE:
 103		return -ENOTSUPP;
 104	case XST_PM_INVALID_VERSION:
 105		return -EOPNOTSUPP;
 106	case XST_PM_NO_ACCESS:
 107		return -EACCES;
 108	case XST_PM_ABORT_SUSPEND:
 109		return -ECANCELED;
 110	case XST_PM_MULT_USER:
 111		return -EUSERS;
 112	case XST_PM_INTERNAL:
 113	case XST_PM_CONFLICT:
 114	case XST_PM_INVALID_NODE:
 115	case XST_PM_INVALID_CRC:
 116	default:
 117		return -EINVAL;
 118	}
 119}
 120
 121static noinline int do_fw_call_fail(u32 *ret_payload, u32 num_args, ...)
 122{
 123	return -ENODEV;
 124}
 125
 126/*
 127 * PM function call wrapper
 128 * Invoke do_fw_call_smc or do_fw_call_hvc, depending on the configuration
 129 */
 130static int (*do_fw_call)(u32 *ret_payload, u32, ...) = do_fw_call_fail;
 131
 132/**
 133 * do_fw_call_smc() - Call system-level platform management layer (SMC)
 134 * @num_args:		Number of variable arguments should be <= 8
 135 * @ret_payload:	Returned value array
 136 *
 137 * Invoke platform management function via SMC call (no hypervisor present).
 138 *
 139 * Return: Returns status, either success or error+reason
 140 */
 141static noinline int do_fw_call_smc(u32 *ret_payload, u32 num_args, ...)
 142{
 143	struct arm_smccc_res res;
 144	u64 args[8] = {0};
 145	va_list arg_list;
 146	u8 i;
 147
 148	if (num_args > 8)
 149		return -EINVAL;
 150
 151	va_start(arg_list, num_args);
 152
 153	for (i = 0; i < num_args; i++)
 154		args[i] = va_arg(arg_list, u64);
 155
 156	va_end(arg_list);
 157
 158	arm_smccc_smc(args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], &res);
 159
 160	if (ret_payload) {
 161		ret_payload[0] = lower_32_bits(res.a0);
 162		ret_payload[1] = upper_32_bits(res.a0);
 163		ret_payload[2] = lower_32_bits(res.a1);
 164		ret_payload[3] = upper_32_bits(res.a1);
 165		ret_payload[4] = lower_32_bits(res.a2);
 166		ret_payload[5] = upper_32_bits(res.a2);
 167		ret_payload[6] = lower_32_bits(res.a3);
 168	}
 169
 170	return zynqmp_pm_ret_code((enum pm_ret_status)res.a0);
 171}
 172
 173/**
 174 * do_fw_call_hvc() - Call system-level platform management layer (HVC)
 175 * @num_args:		Number of variable arguments should be <= 8
 176 * @ret_payload:	Returned value array
 177 *
 178 * Invoke platform management function via HVC
 179 * HVC-based for communication through hypervisor
 180 * (no direct communication with ATF).
 181 *
 182 * Return: Returns status, either success or error+reason
 183 */
 184static noinline int do_fw_call_hvc(u32 *ret_payload, u32 num_args, ...)
 185{
 186	struct arm_smccc_res res;
 187	u64 args[8] = {0};
 188	va_list arg_list;
 189	u8 i;
 190
 191	if (num_args > 8)
 192		return -EINVAL;
 193
 194	va_start(arg_list, num_args);
 195
 196	for (i = 0; i < num_args; i++)
 197		args[i] = va_arg(arg_list, u64);
 198
 199	va_end(arg_list);
 200
 201	arm_smccc_hvc(args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], &res);
 202
 203	if (ret_payload) {
 204		ret_payload[0] = lower_32_bits(res.a0);
 205		ret_payload[1] = upper_32_bits(res.a0);
 206		ret_payload[2] = lower_32_bits(res.a1);
 207		ret_payload[3] = upper_32_bits(res.a1);
 208		ret_payload[4] = lower_32_bits(res.a2);
 209		ret_payload[5] = upper_32_bits(res.a2);
 210		ret_payload[6] = lower_32_bits(res.a3);
 211	}
 212
 213	return zynqmp_pm_ret_code((enum pm_ret_status)res.a0);
 214}
 215
 216static int __do_feature_check_call(const u32 api_id, u32 *ret_payload)
 217{
 218	int ret;
 219	u64 smc_arg[2];
 220	u32 module_id;
 221	u32 feature_check_api_id;
 222
 223	module_id = FIELD_GET(MODULE_ID_MASK, api_id);
 224
 225	/*
 226	 * Feature check of APIs belonging to PM, XSEM, and TF-A are handled by calling
 227	 * PM_FEATURE_CHECK API. For other modules, call PM_API_FEATURES API.
 228	 */
 229	if (module_id == PM_MODULE_ID || module_id == XSEM_MODULE_ID || module_id == TF_A_MODULE_ID)
 230		feature_check_api_id = PM_FEATURE_CHECK;
 231	else
 232		feature_check_api_id = PM_API_FEATURES;
 233
 234	/*
 235	 * Feature check of TF-A APIs is done in the TF-A layer and it expects for
 236	 * MODULE_ID_MASK bits of SMC's arg[0] to be the same as PM_MODULE_ID.
 237	 */
 238	if (module_id == TF_A_MODULE_ID) {
 239		module_id = PM_MODULE_ID;
 240		smc_arg[1] = api_id;
 241	} else {
 242		smc_arg[1] = (api_id & API_ID_MASK);
 243	}
 244
 245	smc_arg[0] = PM_SIP_SVC | FIELD_PREP(MODULE_ID_MASK, module_id) | feature_check_api_id;
 246
 247	ret = do_fw_call(ret_payload, 2, smc_arg[0], smc_arg[1]);
 248	if (ret)
 249		ret = -EOPNOTSUPP;
 250	else
 251		ret = ret_payload[1];
 252
 253	return ret;
 254}
 255
 256static int do_feature_check_call(const u32 api_id)
 257{
 258	int ret;
 259	u32 ret_payload[PAYLOAD_ARG_CNT];
 260	struct pm_api_feature_data *feature_data;
 261
 262	/* Check for existing entry in hash table for given api */
 263	hash_for_each_possible(pm_api_features_map, feature_data, hentry,
 264			       api_id) {
 265		if (feature_data->pm_api_id == api_id)
 266			return feature_data->feature_status;
 267	}
 268
 269	/* Add new entry if not present */
 270	feature_data = kmalloc(sizeof(*feature_data), GFP_ATOMIC);
 271	if (!feature_data)
 272		return -ENOMEM;
 273
 274	feature_data->pm_api_id = api_id;
 275	ret = __do_feature_check_call(api_id, ret_payload);
 276
 277	feature_data->feature_status = ret;
 278	hash_add(pm_api_features_map, &feature_data->hentry, api_id);
 279
 280	if (api_id == PM_IOCTL)
 281		/* Store supported IOCTL IDs mask */
 282		memcpy(ioctl_features, &ret_payload[2], FEATURE_PAYLOAD_SIZE * 4);
 283	else if (api_id == PM_QUERY_DATA)
 284		/* Store supported QUERY IDs mask */
 285		memcpy(query_features, &ret_payload[2], FEATURE_PAYLOAD_SIZE * 4);
 286
 287	return ret;
 288}
 289
 290/**
 291 * zynqmp_pm_feature() - Check whether given feature is supported or not and
 292 *			 store supported IOCTL/QUERY ID mask
 293 * @api_id:		API ID to check
 294 *
 295 * Return: Returns status, either success or error+reason
 296 */
 297int zynqmp_pm_feature(const u32 api_id)
 298{
 299	int ret;
 300
 301	if (!feature_check_enabled)
 302		return 0;
 303
 304	ret = do_feature_check_call(api_id);
 305
 306	return ret;
 307}
 308EXPORT_SYMBOL_GPL(zynqmp_pm_feature);
 309
 310/**
 311 * zynqmp_pm_is_function_supported() - Check whether given IOCTL/QUERY function
 312 *				       is supported or not
 313 * @api_id:		PM_IOCTL or PM_QUERY_DATA
 314 * @id:			IOCTL or QUERY function IDs
 315 *
 316 * Return: Returns status, either success or error+reason
 317 */
 318int zynqmp_pm_is_function_supported(const u32 api_id, const u32 id)
 319{
 320	int ret;
 321	u32 *bit_mask;
 322
 323	/* Input arguments validation */
 324	if (id >= 64 || (api_id != PM_IOCTL && api_id != PM_QUERY_DATA))
 325		return -EINVAL;
 326
 327	/* Check feature check API version */
 328	ret = do_feature_check_call(PM_FEATURE_CHECK);
 329	if (ret < 0)
 330		return ret;
 331
 332	/* Check if feature check version 2 is supported or not */
 333	if ((ret & FIRMWARE_VERSION_MASK) == PM_API_VERSION_2) {
 334		/*
 335		 * Call feature check for IOCTL/QUERY API to get IOCTL ID or
 336		 * QUERY ID feature status.
 337		 */
 338		ret = do_feature_check_call(api_id);
 339		if (ret < 0)
 340			return ret;
 341
 342		bit_mask = (api_id == PM_IOCTL) ? ioctl_features : query_features;
 343
 344		if ((bit_mask[(id / 32)] & BIT((id % 32))) == 0U)
 345			return -EOPNOTSUPP;
 346	} else {
 347		return -ENODATA;
 348	}
 349
 350	return 0;
 351}
 352EXPORT_SYMBOL_GPL(zynqmp_pm_is_function_supported);
 353
 354/**
 355 * zynqmp_pm_invoke_fw_fn() - Invoke the system-level platform management layer
 356 *			caller function depending on the configuration
 357 * @pm_api_id:		Requested PM-API call
 358 * @ret_payload:	Returned value array
 359 * @num_args:		Number of arguments to requested PM-API call
 360 *
 361 * Invoke platform management function for SMC or HVC call, depending on
 362 * configuration.
 363 * Following SMC Calling Convention (SMCCC) for SMC64:
 364 * Pm Function Identifier,
 365 * PM_SIP_SVC + PASS_THROUGH_FW_CMD_ID =
 366 *	((SMC_TYPE_FAST << FUNCID_TYPE_SHIFT)
 367 *	((SMC_64) << FUNCID_CC_SHIFT)
 368 *	((SIP_START) << FUNCID_OEN_SHIFT)
 369 *	(PASS_THROUGH_FW_CMD_ID))
 370 *
 371 * PM_SIP_SVC - Registered ZynqMP SIP Service Call.
 372 * PASS_THROUGH_FW_CMD_ID - Fixed SiP SVC call ID for FW specific calls.
 373 *
 374 * Return: Returns status, either success or error+reason
 375 */
 376int zynqmp_pm_invoke_fw_fn(u32 pm_api_id, u32 *ret_payload, u32 num_args, ...)
 377{
 378	/*
 379	 * Added SIP service call Function Identifier
 380	 * Make sure to stay in x0 register
 381	 */
 382	u64 smc_arg[SMC_ARG_CNT_64];
 383	int ret, i;
 384	va_list arg_list;
 385	u32 args[SMC_ARG_CNT_32] = {0};
 386	u32 module_id;
 387
 388	if (num_args > SMC_ARG_CNT_32)
 389		return -EINVAL;
 390
 391	va_start(arg_list, num_args);
 392
 393	/* Check if feature is supported or not */
 394	ret = zynqmp_pm_feature(pm_api_id);
 395	if (ret < 0)
 396		return ret;
 397
 398	for (i = 0; i < num_args; i++)
 399		args[i] = va_arg(arg_list, u32);
 400
 401	va_end(arg_list);
 402
 403	module_id = FIELD_GET(PLM_MODULE_ID_MASK, pm_api_id);
 404
 405	if (module_id == 0)
 406		module_id = XPM_MODULE_ID;
 407
 408	smc_arg[0] = PM_SIP_SVC | PASS_THROUGH_FW_CMD_ID;
 409	smc_arg[1] = ((u64)args[0] << 32U) | FIELD_PREP(PLM_MODULE_ID_MASK, module_id) |
 410		      (pm_api_id & API_ID_MASK);
 411	for (i = 1; i < (SMC_ARG_CNT_64 - 1); i++)
 412		smc_arg[i + 1] = ((u64)args[(i * 2)] << 32U) | args[(i * 2) - 1];
 413
 414	return do_fw_call(ret_payload, 8, smc_arg[0], smc_arg[1], smc_arg[2], smc_arg[3],
 415			  smc_arg[4], smc_arg[5], smc_arg[6], smc_arg[7]);
 416}
 417
 418/**
 419 * zynqmp_pm_invoke_fn() - Invoke the system-level platform management layer
 420 *			   caller function depending on the configuration
 421 * @pm_api_id:		Requested PM-API call
 422 * @ret_payload:	Returned value array
 423 * @num_args:		Number of arguments to requested PM-API call
 424 *
 425 * Invoke platform management function for SMC or HVC call, depending on
 426 * configuration.
 427 * Following SMC Calling Convention (SMCCC) for SMC64:
 428 * Pm Function Identifier,
 429 * PM_SIP_SVC + PM_API_ID =
 430 *	((SMC_TYPE_FAST << FUNCID_TYPE_SHIFT)
 431 *	((SMC_64) << FUNCID_CC_SHIFT)
 432 *	((SIP_START) << FUNCID_OEN_SHIFT)
 433 *	((PM_API_ID) & FUNCID_NUM_MASK))
 434 *
 435 * PM_SIP_SVC	- Registered ZynqMP SIP Service Call.
 436 * PM_API_ID	- Platform Management API ID.
 437 *
 438 * Return: Returns status, either success or error+reason
 439 */
 440int zynqmp_pm_invoke_fn(u32 pm_api_id, u32 *ret_payload, u32 num_args, ...)
 441{
 442	/*
 443	 * Added SIP service call Function Identifier
 444	 * Make sure to stay in x0 register
 445	 */
 446	u64 smc_arg[8];
 447	int ret, i;
 448	va_list arg_list;
 449	u32 args[14] = {0};
 450
 451	if (num_args > 14)
 452		return -EINVAL;
 453
 454	va_start(arg_list, num_args);
 455
 456	/* Check if feature is supported or not */
 457	ret = zynqmp_pm_feature(pm_api_id);
 458	if (ret < 0)
 459		return ret;
 460
 461	for (i = 0; i < num_args; i++)
 462		args[i] = va_arg(arg_list, u32);
 463
 464	va_end(arg_list);
 465
 466	smc_arg[0] = PM_SIP_SVC | pm_api_id;
 467	for (i = 0; i < 7; i++)
 468		smc_arg[i + 1] = ((u64)args[(i * 2) + 1] << 32) | args[i * 2];
 469
 470	return do_fw_call(ret_payload, 8, smc_arg[0], smc_arg[1], smc_arg[2], smc_arg[3],
 471			  smc_arg[4], smc_arg[5], smc_arg[6], smc_arg[7]);
 472}
 473
 474static u32 pm_api_version;
 475static u32 pm_tz_version;
 476
 477int zynqmp_pm_register_sgi(u32 sgi_num, u32 reset)
 478{
 479	int ret;
 480
 481	ret = zynqmp_pm_invoke_fn(TF_A_PM_REGISTER_SGI, NULL, 2, sgi_num, reset);
 482	if (ret != -EOPNOTSUPP && !ret)
 483		return ret;
 484
 485	/* try old implementation as fallback strategy if above fails */
 486	return zynqmp_pm_invoke_fn(PM_IOCTL, NULL, 3, IOCTL_REGISTER_SGI, sgi_num, reset);
 487}
 488
 489/**
 490 * zynqmp_pm_get_api_version() - Get version number of PMU PM firmware
 491 * @version:	Returned version value
 492 *
 493 * Return: Returns status, either success or error+reason
 494 */
 495int zynqmp_pm_get_api_version(u32 *version)
 496{
 497	u32 ret_payload[PAYLOAD_ARG_CNT];
 498	int ret;
 499
 500	if (!version)
 501		return -EINVAL;
 502
 503	/* Check is PM API version already verified */
 504	if (pm_api_version > 0) {
 505		*version = pm_api_version;
 506		return 0;
 507	}
 508	ret = zynqmp_pm_invoke_fn(PM_GET_API_VERSION, ret_payload, 0);
 509	*version = ret_payload[1];
 510
 511	return ret;
 512}
 513EXPORT_SYMBOL_GPL(zynqmp_pm_get_api_version);
 514
 515/**
 516 * zynqmp_pm_get_chipid - Get silicon ID registers
 517 * @idcode:     IDCODE register
 518 * @version:    version register
 519 *
 520 * Return:      Returns the status of the operation and the idcode and version
 521 *              registers in @idcode and @version.
 522 */
 523int zynqmp_pm_get_chipid(u32 *idcode, u32 *version)
 524{
 525	u32 ret_payload[PAYLOAD_ARG_CNT];
 526	int ret;
 527
 528	if (!idcode || !version)
 529		return -EINVAL;
 530
 531	ret = zynqmp_pm_invoke_fn(PM_GET_CHIPID, ret_payload, 0);
 532	*idcode = ret_payload[1];
 533	*version = ret_payload[2];
 534
 535	return ret;
 536}
 537EXPORT_SYMBOL_GPL(zynqmp_pm_get_chipid);
 538
 539/**
 540 * zynqmp_pm_get_family_info() - Get family info of platform
 541 * @family:	Returned family code value
 542 *
 543 * Return: Returns status, either success or error+reason
 544 */
 545int zynqmp_pm_get_family_info(u32 *family)
 546{
 547	if (!active_platform_fw_data)
 548		return -ENODEV;
 549
 550	if (!family)
 551		return -EINVAL;
 552
 553	*family = active_platform_fw_data->family_code;
 554
 555	return 0;
 556}
 557EXPORT_SYMBOL_GPL(zynqmp_pm_get_family_info);
 558
 559/**
 560 * zynqmp_pm_get_sip_svc_version() - Get SiP service call version
 561 * @version:	Returned version value
 562 *
 563 * Return: Returns status, either success or error+reason
 564 */
 565static int zynqmp_pm_get_sip_svc_version(u32 *version)
 566{
 567	struct arm_smccc_res res;
 568	u64 args[SMC_ARG_CNT_64] = {0};
 569
 570	if (!version)
 571		return -EINVAL;
 572
 573	/* Check if SiP SVC version already verified */
 574	if (sip_svc_version > 0) {
 575		*version = sip_svc_version;
 576		return 0;
 577	}
 578
 579	args[0] = GET_SIP_SVC_VERSION;
 580
 581	arm_smccc_smc(args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], &res);
 582
 583	*version = ((lower_32_bits(res.a0) << 16U) | lower_32_bits(res.a1));
 584
 585	return zynqmp_pm_ret_code(XST_PM_SUCCESS);
 586}
 587
 588/**
 589 * zynqmp_pm_get_trustzone_version() - Get secure trustzone firmware version
 590 * @version:	Returned version value
 591 *
 592 * Return: Returns status, either success or error+reason
 593 */
 594static int zynqmp_pm_get_trustzone_version(u32 *version)
 595{
 596	u32 ret_payload[PAYLOAD_ARG_CNT];
 597	int ret;
 598
 599	if (!version)
 600		return -EINVAL;
 601
 602	/* Check is PM trustzone version already verified */
 603	if (pm_tz_version > 0) {
 604		*version = pm_tz_version;
 605		return 0;
 606	}
 607	ret = zynqmp_pm_invoke_fn(PM_GET_TRUSTZONE_VERSION, ret_payload, 0);
 608	*version = ret_payload[1];
 609
 610	return ret;
 611}
 612
 613/**
 614 * get_set_conduit_method() - Choose SMC or HVC based communication
 615 * @np:		Pointer to the device_node structure
 616 *
 617 * Use SMC or HVC-based functions to communicate with EL2/EL3.
 618 *
 619 * Return: Returns 0 on success or error code
 620 */
 621static int get_set_conduit_method(struct device_node *np)
 622{
 623	const char *method;
 624
 625	if (of_property_read_string(np, "method", &method)) {
 626		pr_warn("%s missing \"method\" property\n", __func__);
 627		return -ENXIO;
 628	}
 629
 630	if (!strcmp("hvc", method)) {
 631		do_fw_call = do_fw_call_hvc;
 632	} else if (!strcmp("smc", method)) {
 633		do_fw_call = do_fw_call_smc;
 634	} else {
 635		pr_warn("%s Invalid \"method\" property: %s\n",
 636			__func__, method);
 637		return -EINVAL;
 638	}
 639
 640	return 0;
 641}
 642
 643/**
 644 * zynqmp_pm_query_data() - Get query data from firmware
 645 * @qdata:	Variable to the zynqmp_pm_query_data structure
 646 * @out:	Returned output value
 647 *
 648 * Return: Returns status, either success or error+reason
 649 */
 650int zynqmp_pm_query_data(struct zynqmp_pm_query_data qdata, u32 *out)
 651{
 652	int ret, i = 0;
 653	u32 ret_payload[PAYLOAD_ARG_CNT] = {0};
 654
 655	if (sip_svc_version >= SIP_SVC_PASSTHROUGH_VERSION) {
 656		ret = zynqmp_pm_invoke_fw_fn(PM_QUERY_DATA, ret_payload, 4,
 657					     qdata.qid, qdata.arg1,
 658					     qdata.arg2, qdata.arg3);
 659		/* To support backward compatibility */
 660		if (!ret && !ret_payload[0]) {
 661			/*
 662			 * TF-A passes return status on 0th index but
 663			 * api to get clock name reads data from 0th
 664			 * index so pass data at 0th index instead of
 665			 * return status
 666			 */
 667			if (qdata.qid == PM_QID_CLOCK_GET_NAME ||
 668			    qdata.qid == PM_QID_PINCTRL_GET_FUNCTION_NAME)
 669				i = 1;
 670
 671			for (; i < PAYLOAD_ARG_CNT; i++, out++)
 672				*out = ret_payload[i];
 673
 674			return ret;
 675		}
 676	}
 677
 678	ret = zynqmp_pm_invoke_fn(PM_QUERY_DATA, out, 4, qdata.qid,
 679				  qdata.arg1, qdata.arg2, qdata.arg3);
 680
 681	/*
 682	 * For clock name query, all bytes in SMC response are clock name
 683	 * characters and return code is always success. For invalid clocks,
 684	 * clock name bytes would be zeros.
 685	 */
 686	return qdata.qid == PM_QID_CLOCK_GET_NAME ? 0 : ret;
 687}
 688EXPORT_SYMBOL_GPL(zynqmp_pm_query_data);
 689
 690/**
 691 * zynqmp_pm_clock_enable() - Enable the clock for given id
 692 * @clock_id:	ID of the clock to be enabled
 693 *
 694 * This function is used by master to enable the clock
 695 * including peripherals and PLL clocks.
 696 *
 697 * Return: Returns status, either success or error+reason
 698 */
 699int zynqmp_pm_clock_enable(u32 clock_id)
 700{
 701	return zynqmp_pm_invoke_fn(PM_CLOCK_ENABLE, NULL, 1, clock_id);
 702}
 703EXPORT_SYMBOL_GPL(zynqmp_pm_clock_enable);
 704
 705/**
 706 * zynqmp_pm_clock_disable() - Disable the clock for given id
 707 * @clock_id:	ID of the clock to be disable
 708 *
 709 * This function is used by master to disable the clock
 710 * including peripherals and PLL clocks.
 711 *
 712 * Return: Returns status, either success or error+reason
 713 */
 714int zynqmp_pm_clock_disable(u32 clock_id)
 715{
 716	return zynqmp_pm_invoke_fn(PM_CLOCK_DISABLE, NULL, 1, clock_id);
 717}
 718EXPORT_SYMBOL_GPL(zynqmp_pm_clock_disable);
 719
 720/**
 721 * zynqmp_pm_clock_getstate() - Get the clock state for given id
 722 * @clock_id:	ID of the clock to be queried
 723 * @state:	1/0 (Enabled/Disabled)
 724 *
 725 * This function is used by master to get the state of clock
 726 * including peripherals and PLL clocks.
 727 *
 728 * Return: Returns status, either success or error+reason
 729 */
 730int zynqmp_pm_clock_getstate(u32 clock_id, u32 *state)
 731{
 732	u32 ret_payload[PAYLOAD_ARG_CNT];
 733	int ret;
 734
 735	ret = zynqmp_pm_invoke_fn(PM_CLOCK_GETSTATE, ret_payload, 1, clock_id);
 736	*state = ret_payload[1];
 737
 738	return ret;
 739}
 740EXPORT_SYMBOL_GPL(zynqmp_pm_clock_getstate);
 741
 742/**
 743 * zynqmp_pm_clock_setdivider() - Set the clock divider for given id
 744 * @clock_id:	ID of the clock
 745 * @divider:	divider value
 746 *
 747 * This function is used by master to set divider for any clock
 748 * to achieve desired rate.
 749 *
 750 * Return: Returns status, either success or error+reason
 751 */
 752int zynqmp_pm_clock_setdivider(u32 clock_id, u32 divider)
 753{
 754	return zynqmp_pm_invoke_fn(PM_CLOCK_SETDIVIDER, NULL, 2, clock_id, divider);
 755}
 756EXPORT_SYMBOL_GPL(zynqmp_pm_clock_setdivider);
 757
 758/**
 759 * zynqmp_pm_clock_getdivider() - Get the clock divider for given id
 760 * @clock_id:	ID of the clock
 761 * @divider:	divider value
 762 *
 763 * This function is used by master to get divider values
 764 * for any clock.
 765 *
 766 * Return: Returns status, either success or error+reason
 767 */
 768int zynqmp_pm_clock_getdivider(u32 clock_id, u32 *divider)
 769{
 770	u32 ret_payload[PAYLOAD_ARG_CNT];
 771	int ret;
 772
 773	ret = zynqmp_pm_invoke_fn(PM_CLOCK_GETDIVIDER, ret_payload, 1, clock_id);
 774	*divider = ret_payload[1];
 775
 776	return ret;
 777}
 778EXPORT_SYMBOL_GPL(zynqmp_pm_clock_getdivider);
 779
 780/**
 781 * zynqmp_pm_clock_setparent() - Set the clock parent for given id
 782 * @clock_id:	ID of the clock
 783 * @parent_id:	parent id
 784 *
 785 * This function is used by master to set parent for any clock.
 786 *
 787 * Return: Returns status, either success or error+reason
 788 */
 789int zynqmp_pm_clock_setparent(u32 clock_id, u32 parent_id)
 790{
 791	return zynqmp_pm_invoke_fn(PM_CLOCK_SETPARENT, NULL, 2, clock_id, parent_id);
 792}
 793EXPORT_SYMBOL_GPL(zynqmp_pm_clock_setparent);
 794
 795/**
 796 * zynqmp_pm_clock_getparent() - Get the clock parent for given id
 797 * @clock_id:	ID of the clock
 798 * @parent_id:	parent id
 799 *
 800 * This function is used by master to get parent index
 801 * for any clock.
 802 *
 803 * Return: Returns status, either success or error+reason
 804 */
 805int zynqmp_pm_clock_getparent(u32 clock_id, u32 *parent_id)
 806{
 807	u32 ret_payload[PAYLOAD_ARG_CNT];
 808	int ret;
 809
 810	ret = zynqmp_pm_invoke_fn(PM_CLOCK_GETPARENT, ret_payload, 1, clock_id);
 811	*parent_id = ret_payload[1];
 812
 813	return ret;
 814}
 815EXPORT_SYMBOL_GPL(zynqmp_pm_clock_getparent);
 816
 817/**
 818 * zynqmp_pm_set_pll_frac_mode() - PM API for set PLL mode
 819 *
 820 * @clk_id:	PLL clock ID
 821 * @mode:	PLL mode (PLL_MODE_FRAC/PLL_MODE_INT)
 822 *
 823 * This function sets PLL mode
 824 *
 825 * Return: Returns status, either success or error+reason
 826 */
 827int zynqmp_pm_set_pll_frac_mode(u32 clk_id, u32 mode)
 828{
 829	return zynqmp_pm_invoke_fn(PM_IOCTL, NULL, 4, 0, IOCTL_SET_PLL_FRAC_MODE, clk_id, mode);
 830}
 831EXPORT_SYMBOL_GPL(zynqmp_pm_set_pll_frac_mode);
 832
 833/**
 834 * zynqmp_pm_get_pll_frac_mode() - PM API for get PLL mode
 835 *
 836 * @clk_id:	PLL clock ID
 837 * @mode:	PLL mode
 838 *
 839 * This function return current PLL mode
 840 *
 841 * Return: Returns status, either success or error+reason
 842 */
 843int zynqmp_pm_get_pll_frac_mode(u32 clk_id, u32 *mode)
 844{
 845	return zynqmp_pm_invoke_fn(PM_IOCTL, mode, 3, 0, IOCTL_GET_PLL_FRAC_MODE, clk_id);
 846}
 847EXPORT_SYMBOL_GPL(zynqmp_pm_get_pll_frac_mode);
 848
 849/**
 850 * zynqmp_pm_set_pll_frac_data() - PM API for setting pll fraction data
 851 *
 852 * @clk_id:	PLL clock ID
 853 * @data:	fraction data
 854 *
 855 * This function sets fraction data.
 856 * It is valid for fraction mode only.
 857 *
 858 * Return: Returns status, either success or error+reason
 859 */
 860int zynqmp_pm_set_pll_frac_data(u32 clk_id, u32 data)
 861{
 862	return zynqmp_pm_invoke_fn(PM_IOCTL, NULL, 4, 0, IOCTL_SET_PLL_FRAC_DATA, clk_id, data);
 863}
 864EXPORT_SYMBOL_GPL(zynqmp_pm_set_pll_frac_data);
 865
 866/**
 867 * zynqmp_pm_get_pll_frac_data() - PM API for getting pll fraction data
 868 *
 869 * @clk_id:	PLL clock ID
 870 * @data:	fraction data
 871 *
 872 * This function returns fraction data value.
 873 *
 874 * Return: Returns status, either success or error+reason
 875 */
 876int zynqmp_pm_get_pll_frac_data(u32 clk_id, u32 *data)
 877{
 878	return zynqmp_pm_invoke_fn(PM_IOCTL, data, 3, 0, IOCTL_GET_PLL_FRAC_DATA, clk_id);
 879}
 880EXPORT_SYMBOL_GPL(zynqmp_pm_get_pll_frac_data);
 881
 882/**
 883 * zynqmp_pm_set_sd_tapdelay() -  Set tap delay for the SD device
 884 *
 885 * @node_id:	Node ID of the device
 886 * @type:	Type of tap delay to set (input/output)
 887 * @value:	Value to set fot the tap delay
 888 *
 889 * This function sets input/output tap delay for the SD device.
 890 *
 891 * Return:	Returns status, either success or error+reason
 892 */
 893int zynqmp_pm_set_sd_tapdelay(u32 node_id, u32 type, u32 value)
 894{
 895	u32 reg = (type == PM_TAPDELAY_INPUT) ? SD_ITAPDLY : SD_OTAPDLYSEL;
 896	u32 mask = (node_id == NODE_SD_0) ? GENMASK(15, 0) : GENMASK(31, 16);
 897
 898	if (value) {
 899		return zynqmp_pm_invoke_fn(PM_IOCTL, NULL, 4, node_id, IOCTL_SET_SD_TAPDELAY, type,
 900					   value);
 901	}
 902
 903	/*
 904	 * Work around completely misdesigned firmware API on Xilinx ZynqMP.
 905	 * The IOCTL_SET_SD_TAPDELAY firmware call allows the caller to only
 906	 * ever set IOU_SLCR SD_ITAPDLY Register SD0_ITAPDLYENA/SD1_ITAPDLYENA
 907	 * bits, but there is no matching call to clear those bits. If those
 908	 * bits are not cleared, SDMMC tuning may fail.
 909	 *
 910	 * Luckily, there are PM_MMIO_READ/PM_MMIO_WRITE calls which seem to
 911	 * allow complete unrestricted access to all address space, including
 912	 * IOU_SLCR SD_ITAPDLY Register and all the other registers, access
 913	 * to which was supposed to be protected by the current firmware API.
 914	 *
 915	 * Use PM_MMIO_READ/PM_MMIO_WRITE to re-implement the missing counter
 916	 * part of IOCTL_SET_SD_TAPDELAY which clears SDx_ITAPDLYENA bits.
 917	 */
 918	return zynqmp_pm_invoke_fn(PM_MMIO_WRITE, NULL, 2, reg, mask);
 919}
 920EXPORT_SYMBOL_GPL(zynqmp_pm_set_sd_tapdelay);
 921
 922/**
 923 * zynqmp_pm_sd_dll_reset() - Reset DLL logic
 924 *
 925 * @node_id:	Node ID of the device
 926 * @type:	Reset type
 927 *
 928 * This function resets DLL logic for the SD device.
 929 *
 930 * Return:	Returns status, either success or error+reason
 931 */
 932int zynqmp_pm_sd_dll_reset(u32 node_id, u32 type)
 933{
 934	return zynqmp_pm_invoke_fn(PM_IOCTL, NULL, 3, node_id, IOCTL_SD_DLL_RESET, type);
 935}
 936EXPORT_SYMBOL_GPL(zynqmp_pm_sd_dll_reset);
 937
 938/**
 939 * zynqmp_pm_ospi_mux_select() - OSPI Mux selection
 940 *
 941 * @dev_id:	Device Id of the OSPI device.
 942 * @select:	OSPI Mux select value.
 943 *
 944 * This function select the OSPI Mux.
 945 *
 946 * Return:	Returns status, either success or error+reason
 947 */
 948int zynqmp_pm_ospi_mux_select(u32 dev_id, u32 select)
 949{
 950	return zynqmp_pm_invoke_fn(PM_IOCTL, NULL, 3, dev_id, IOCTL_OSPI_MUX_SELECT, select);
 951}
 952EXPORT_SYMBOL_GPL(zynqmp_pm_ospi_mux_select);
 953
 954/**
 955 * zynqmp_pm_write_ggs() - PM API for writing global general storage (ggs)
 956 * @index:	GGS register index
 957 * @value:	Register value to be written
 958 *
 959 * This function writes value to GGS register.
 960 *
 961 * Return:      Returns status, either success or error+reason
 962 */
 963int zynqmp_pm_write_ggs(u32 index, u32 value)
 964{
 965	return zynqmp_pm_invoke_fn(PM_IOCTL, NULL, 4, 0, IOCTL_WRITE_GGS, index, value);
 966}
 967EXPORT_SYMBOL_GPL(zynqmp_pm_write_ggs);
 968
 969/**
 970 * zynqmp_pm_read_ggs() - PM API for reading global general storage (ggs)
 971 * @index:	GGS register index
 972 * @value:	Register value to be written
 973 *
 974 * This function returns GGS register value.
 975 *
 976 * Return:	Returns status, either success or error+reason
 977 */
 978int zynqmp_pm_read_ggs(u32 index, u32 *value)
 979{
 980	return zynqmp_pm_invoke_fn(PM_IOCTL, value, 3, 0, IOCTL_READ_GGS, index);
 981}
 982EXPORT_SYMBOL_GPL(zynqmp_pm_read_ggs);
 983
 984/**
 985 * zynqmp_pm_write_pggs() - PM API for writing persistent global general
 986 *			     storage (pggs)
 987 * @index:	PGGS register index
 988 * @value:	Register value to be written
 989 *
 990 * This function writes value to PGGS register.
 991 *
 992 * Return:	Returns status, either success or error+reason
 993 */
 994int zynqmp_pm_write_pggs(u32 index, u32 value)
 995{
 996	return zynqmp_pm_invoke_fn(PM_IOCTL, NULL, 4, 0, IOCTL_WRITE_PGGS, index, value);
 997}
 998EXPORT_SYMBOL_GPL(zynqmp_pm_write_pggs);
 999
1000/**
1001 * zynqmp_pm_read_pggs() - PM API for reading persistent global general
1002 *			     storage (pggs)
1003 * @index:	PGGS register index
1004 * @value:	Register value to be written
1005 *
1006 * This function returns PGGS register value.
1007 *
1008 * Return:	Returns status, either success or error+reason
1009 */
1010int zynqmp_pm_read_pggs(u32 index, u32 *value)
1011{
1012	return zynqmp_pm_invoke_fn(PM_IOCTL, value, 3, 0, IOCTL_READ_PGGS, index);
1013}
1014EXPORT_SYMBOL_GPL(zynqmp_pm_read_pggs);
1015
1016int zynqmp_pm_set_tapdelay_bypass(u32 index, u32 value)
1017{
1018	return zynqmp_pm_invoke_fn(PM_IOCTL, NULL, 4, 0, IOCTL_SET_TAPDELAY_BYPASS, index, value);
1019}
1020EXPORT_SYMBOL_GPL(zynqmp_pm_set_tapdelay_bypass);
1021
1022/**
1023 * zynqmp_pm_set_boot_health_status() - PM API for setting healthy boot status
1024 * @value:	Status value to be written
1025 *
1026 * This function sets healthy bit value to indicate boot health status
1027 * to firmware.
1028 *
1029 * Return:	Returns status, either success or error+reason
1030 */
1031int zynqmp_pm_set_boot_health_status(u32 value)
1032{
1033	return zynqmp_pm_invoke_fn(PM_IOCTL, NULL, 3, 0, IOCTL_SET_BOOT_HEALTH_STATUS, value);
1034}
1035
1036/**
1037 * zynqmp_pm_reset_assert - Request setting of reset (1 - assert, 0 - release)
1038 * @reset:		Reset to be configured
1039 * @assert_flag:	Flag stating should reset be asserted (1) or
1040 *			released (0)
1041 *
1042 * Return: Returns status, either success or error+reason
1043 */
1044int zynqmp_pm_reset_assert(const u32 reset,
1045			   const enum zynqmp_pm_reset_action assert_flag)
1046{
1047	return zynqmp_pm_invoke_fn(PM_RESET_ASSERT, NULL, 2, reset, assert_flag);
1048}
1049EXPORT_SYMBOL_GPL(zynqmp_pm_reset_assert);
1050
1051/**
1052 * zynqmp_pm_reset_get_status - Get status of the reset
1053 * @reset:      Reset whose status should be returned
1054 * @status:     Returned status
1055 *
1056 * Return: Returns status, either success or error+reason
1057 */
1058int zynqmp_pm_reset_get_status(const u32 reset, u32 *status)
1059{
1060	u32 ret_payload[PAYLOAD_ARG_CNT];
1061	int ret;
1062
1063	if (!status)
1064		return -EINVAL;
1065
1066	ret = zynqmp_pm_invoke_fn(PM_RESET_GET_STATUS, ret_payload, 1, reset);
1067	*status = ret_payload[1];
1068
1069	return ret;
1070}
1071EXPORT_SYMBOL_GPL(zynqmp_pm_reset_get_status);
1072
1073/**
1074 * zynqmp_pm_fpga_load - Perform the fpga load
1075 * @address:	Address to write to
1076 * @size:	pl bitstream size
1077 * @flags:	Bitstream type
1078 *	-XILINX_ZYNQMP_PM_FPGA_FULL:  FPGA full reconfiguration
1079 *	-XILINX_ZYNQMP_PM_FPGA_PARTIAL: FPGA partial reconfiguration
1080 *
1081 * This function provides access to pmufw. To transfer
1082 * the required bitstream into PL.
1083 *
1084 * Return: Returns status, either success or error+reason
1085 */
1086int zynqmp_pm_fpga_load(const u64 address, const u32 size, const u32 flags)
1087{
1088	u32 ret_payload[PAYLOAD_ARG_CNT];
1089	int ret;
1090
1091	ret = zynqmp_pm_invoke_fn(PM_FPGA_LOAD, ret_payload, 4, lower_32_bits(address),
1092				  upper_32_bits(address), size, flags);
1093	if (ret_payload[0])
1094		return -ret_payload[0];
1095
1096	return ret;
1097}
1098EXPORT_SYMBOL_GPL(zynqmp_pm_fpga_load);
1099
1100/**
1101 * zynqmp_pm_fpga_get_status - Read value from PCAP status register
1102 * @value: Value to read
1103 *
1104 * This function provides access to the pmufw to get the PCAP
1105 * status
1106 *
1107 * Return: Returns status, either success or error+reason
1108 */
1109int zynqmp_pm_fpga_get_status(u32 *value)
1110{
1111	u32 ret_payload[PAYLOAD_ARG_CNT];
1112	int ret;
1113
1114	if (!value)
1115		return -EINVAL;
1116
1117	ret = zynqmp_pm_invoke_fn(PM_FPGA_GET_STATUS, ret_payload, 0);
1118	*value = ret_payload[1];
1119
1120	return ret;
1121}
1122EXPORT_SYMBOL_GPL(zynqmp_pm_fpga_get_status);
1123
1124/**
1125 * zynqmp_pm_fpga_get_config_status - Get the FPGA configuration status.
1126 * @value: Buffer to store FPGA configuration status.
1127 *
1128 * This function provides access to the pmufw to get the FPGA configuration
1129 * status
1130 *
1131 * Return: 0 on success, a negative value on error
1132 */
1133int zynqmp_pm_fpga_get_config_status(u32 *value)
1134{
1135	u32 ret_payload[PAYLOAD_ARG_CNT];
1136	int ret;
1137
1138	if (!value)
1139		return -EINVAL;
1140
1141	ret = zynqmp_pm_invoke_fn(PM_FPGA_READ, ret_payload, 4,
1142				  XILINX_ZYNQMP_PM_FPGA_CONFIG_STAT_OFFSET, 0, 0,
1143				  XILINX_ZYNQMP_PM_FPGA_READ_CONFIG_REG);
1144
1145	*value = ret_payload[1];
1146
1147	return ret;
1148}
1149EXPORT_SYMBOL_GPL(zynqmp_pm_fpga_get_config_status);
1150
1151/**
1152 * zynqmp_pm_pinctrl_request - Request Pin from firmware
1153 * @pin: Pin number to request
1154 *
1155 * This function requests pin from firmware.
1156 *
1157 * Return: Returns status, either success or error+reason.
1158 */
1159int zynqmp_pm_pinctrl_request(const u32 pin)
1160{
1161	return zynqmp_pm_invoke_fn(PM_PINCTRL_REQUEST, NULL, 1, pin);
1162}
1163EXPORT_SYMBOL_GPL(zynqmp_pm_pinctrl_request);
1164
1165/**
1166 * zynqmp_pm_pinctrl_release - Inform firmware that Pin control is released
1167 * @pin: Pin number to release
1168 *
1169 * This function release pin from firmware.
1170 *
1171 * Return: Returns status, either success or error+reason.
1172 */
1173int zynqmp_pm_pinctrl_release(const u32 pin)
1174{
1175	return zynqmp_pm_invoke_fn(PM_PINCTRL_RELEASE, NULL, 1, pin);
1176}
1177EXPORT_SYMBOL_GPL(zynqmp_pm_pinctrl_release);
1178
1179/**
1180 * zynqmp_pm_pinctrl_set_function - Set requested function for the pin
1181 * @pin: Pin number
1182 * @id: Function ID to set
1183 *
1184 * This function sets requested function for the given pin.
1185 *
1186 * Return: Returns status, either success or error+reason.
1187 */
1188int zynqmp_pm_pinctrl_set_function(const u32 pin, const u32 id)
1189{
1190	return zynqmp_pm_invoke_fn(PM_PINCTRL_SET_FUNCTION, NULL, 2, pin, id);
1191}
1192EXPORT_SYMBOL_GPL(zynqmp_pm_pinctrl_set_function);
1193
1194/**
1195 * zynqmp_pm_pinctrl_get_config - Get configuration parameter for the pin
1196 * @pin: Pin number
1197 * @param: Parameter to get
1198 * @value: Buffer to store parameter value
1199 *
1200 * This function gets requested configuration parameter for the given pin.
1201 *
1202 * Return: Returns status, either success or error+reason.
1203 */
1204int zynqmp_pm_pinctrl_get_config(const u32 pin, const u32 param,
1205				 u32 *value)
1206{
1207	u32 ret_payload[PAYLOAD_ARG_CNT];
1208	int ret;
1209
1210	if (!value)
1211		return -EINVAL;
1212
1213	ret = zynqmp_pm_invoke_fn(PM_PINCTRL_CONFIG_PARAM_GET, ret_payload, 2, pin, param);
1214	*value = ret_payload[1];
1215
1216	return ret;
1217}
1218EXPORT_SYMBOL_GPL(zynqmp_pm_pinctrl_get_config);
1219
1220/**
1221 * zynqmp_pm_pinctrl_set_config - Set configuration parameter for the pin
1222 * @pin: Pin number
1223 * @param: Parameter to set
1224 * @value: Parameter value to set
1225 *
1226 * This function sets requested configuration parameter for the given pin.
1227 *
1228 * Return: Returns status, either success or error+reason.
1229 */
1230int zynqmp_pm_pinctrl_set_config(const u32 pin, const u32 param,
1231				 u32 value)
1232{
1233	int ret;
1234	u32 pm_family_code;
1235
1236	ret = zynqmp_pm_get_family_info(&pm_family_code);
1237	if (ret)
1238		return ret;
1239
1240	if (pm_family_code == PM_ZYNQMP_FAMILY_CODE &&
1241	    param == PM_PINCTRL_CONFIG_TRI_STATE) {
1242		ret = zynqmp_pm_feature(PM_PINCTRL_CONFIG_PARAM_SET);
1243		if (ret < PM_PINCTRL_PARAM_SET_VERSION) {
1244			pr_warn("The requested pinctrl feature is not supported in the current firmware.\n"
1245				"Expected firmware version is 2023.1 and above for this feature to work.\r\n");
1246			return -EOPNOTSUPP;
1247		}
1248	}
1249
1250	return zynqmp_pm_invoke_fn(PM_PINCTRL_CONFIG_PARAM_SET, NULL, 3, pin, param, value);
1251}
1252EXPORT_SYMBOL_GPL(zynqmp_pm_pinctrl_set_config);
1253
1254/**
1255 * zynqmp_pm_bootmode_read() - PM Config API for read bootpin status
1256 * @ps_mode: Returned output value of ps_mode
1257 *
1258 * This API function is to be used for notify the power management controller
1259 * to read bootpin status.
1260 *
1261 * Return: status, either success or error+reason
1262 */
1263unsigned int zynqmp_pm_bootmode_read(u32 *ps_mode)
1264{
1265	unsigned int ret;
1266	u32 ret_payload[PAYLOAD_ARG_CNT];
1267
1268	ret = zynqmp_pm_invoke_fn(PM_MMIO_READ, ret_payload, 1, CRL_APB_BOOT_PIN_CTRL);
1269
1270	*ps_mode = ret_payload[1];
1271
1272	return ret;
1273}
1274EXPORT_SYMBOL_GPL(zynqmp_pm_bootmode_read);
1275
1276/**
1277 * zynqmp_pm_bootmode_write() - PM Config API for Configure bootpin
1278 * @ps_mode: Value to be written to the bootpin ctrl register
1279 *
1280 * This API function is to be used for notify the power management controller
1281 * to configure bootpin.
1282 *
1283 * Return: Returns status, either success or error+reason
1284 */
1285int zynqmp_pm_bootmode_write(u32 ps_mode)
1286{
1287	return zynqmp_pm_invoke_fn(PM_MMIO_WRITE, NULL, 3, CRL_APB_BOOT_PIN_CTRL,
1288				   CRL_APB_BOOTPIN_CTRL_MASK, ps_mode);
1289}
1290EXPORT_SYMBOL_GPL(zynqmp_pm_bootmode_write);
1291
1292/**
1293 * zynqmp_pm_init_finalize() - PM call to inform firmware that the caller
1294 *			       master has initialized its own power management
1295 *
1296 * Return: Returns status, either success or error+reason
1297 *
1298 * This API function is to be used for notify the power management controller
1299 * about the completed power management initialization.
1300 */
1301static int zynqmp_pm_init_finalize(void)
1302{
1303	return zynqmp_pm_invoke_fn(PM_PM_INIT_FINALIZE, NULL, 0);
1304}
1305
1306/**
1307 * zynqmp_pm_set_suspend_mode()	- Set system suspend mode
1308 * @mode:	Mode to set for system suspend
1309 *
1310 * This API function is used to set mode of system suspend.
1311 *
1312 * Return: Returns status, either success or error+reason
1313 */
1314int zynqmp_pm_set_suspend_mode(u32 mode)
1315{
1316	return zynqmp_pm_invoke_fn(PM_SET_SUSPEND_MODE, NULL, 1, mode);
1317}
1318EXPORT_SYMBOL_GPL(zynqmp_pm_set_suspend_mode);
1319
1320/**
1321 * zynqmp_pm_request_node() - Request a node with specific capabilities
1322 * @node:		Node ID of the slave
1323 * @capabilities:	Requested capabilities of the slave
1324 * @qos:		Quality of service (not supported)
1325 * @ack:		Flag to specify whether acknowledge is requested
1326 *
1327 * This function is used by master to request particular node from firmware.
1328 * Every master must request node before using it.
1329 *
1330 * Return: Returns status, either success or error+reason
1331 */
1332int zynqmp_pm_request_node(const u32 node, const u32 capabilities,
1333			   const u32 qos, const enum zynqmp_pm_request_ack ack)
1334{
1335	return zynqmp_pm_invoke_fn(PM_REQUEST_NODE, NULL, 4, node, capabilities, qos, ack);
1336}
1337EXPORT_SYMBOL_GPL(zynqmp_pm_request_node);
1338
1339/**
1340 * zynqmp_pm_release_node() - Release a node
1341 * @node:	Node ID of the slave
1342 *
1343 * This function is used by master to inform firmware that master
1344 * has released node. Once released, master must not use that node
1345 * without re-request.
1346 *
1347 * Return: Returns status, either success or error+reason
1348 */
1349int zynqmp_pm_release_node(const u32 node)
1350{
1351	return zynqmp_pm_invoke_fn(PM_RELEASE_NODE, NULL, 1, node);
1352}
1353EXPORT_SYMBOL_GPL(zynqmp_pm_release_node);
1354
1355/**
1356 * zynqmp_pm_get_rpu_mode() - Get RPU mode
1357 * @node_id:	Node ID of the device
1358 * @rpu_mode:	return by reference value
1359 *		either split or lockstep
1360 *
1361 * Return:	return 0 on success or error+reason.
1362 *		if success, then  rpu_mode will be set
1363 *		to current rpu mode.
1364 */
1365int zynqmp_pm_get_rpu_mode(u32 node_id, enum rpu_oper_mode *rpu_mode)
1366{
1367	u32 ret_payload[PAYLOAD_ARG_CNT];
1368	int ret;
1369
1370	ret = zynqmp_pm_invoke_fn(PM_IOCTL, ret_payload, 2, node_id, IOCTL_GET_RPU_OPER_MODE);
1371
1372	/* only set rpu_mode if no error */
1373	if (ret == XST_PM_SUCCESS)
1374		*rpu_mode = ret_payload[0];
1375
1376	return ret;
1377}
1378EXPORT_SYMBOL_GPL(zynqmp_pm_get_rpu_mode);
1379
1380/**
1381 * zynqmp_pm_set_rpu_mode() - Set RPU mode
1382 * @node_id:	Node ID of the device
1383 * @rpu_mode:	Argument 1 to requested IOCTL call. either split or lockstep
1384 *
1385 *		This function is used to set RPU mode to split or
1386 *		lockstep
1387 *
1388 * Return:	Returns status, either success or error+reason
1389 */
1390int zynqmp_pm_set_rpu_mode(u32 node_id, enum rpu_oper_mode rpu_mode)
1391{
1392	return zynqmp_pm_invoke_fn(PM_IOCTL, NULL, 3, node_id, IOCTL_SET_RPU_OPER_MODE,
1393				   (u32)rpu_mode);
1394}
1395EXPORT_SYMBOL_GPL(zynqmp_pm_set_rpu_mode);
1396
1397/**
1398 * zynqmp_pm_set_tcm_config - configure TCM
1399 * @node_id:	Firmware specific TCM subsystem ID
1400 * @tcm_mode:	Argument 1 to requested IOCTL call
1401 *              either PM_RPU_TCM_COMB or PM_RPU_TCM_SPLIT
1402 *
1403 * This function is used to set RPU mode to split or combined
1404 *
1405 * Return: status: 0 for success, else failure
1406 */
1407int zynqmp_pm_set_tcm_config(u32 node_id, enum rpu_tcm_comb tcm_mode)
1408{
1409	return zynqmp_pm_invoke_fn(PM_IOCTL, NULL, 3, node_id, IOCTL_TCM_COMB_CONFIG,
1410				   (u32)tcm_mode);
1411}
1412EXPORT_SYMBOL_GPL(zynqmp_pm_set_tcm_config);
1413
1414/**
1415 * zynqmp_pm_get_node_status - PM call to request a node's current power state
1416 * @node:		ID of the component or sub-system in question
1417 * @status:		Current operating state of the requested node
1418 * @requirements:	Current requirements asserted on the node,
1419 *			used for slave nodes only.
1420 * @usage:		Usage information, used for slave nodes only:
1421 *			PM_USAGE_NO_MASTER	- No master is currently using
1422 *						  the node
1423 *			PM_USAGE_CURRENT_MASTER	- Only requesting master is
1424 *						  currently using the node
1425 *			PM_USAGE_OTHER_MASTER	- Only other masters are
1426 *						  currently using the node
1427 *			PM_USAGE_BOTH_MASTERS	- Both the current and at least
1428 *						  one other master is currently
1429 *						  using the node
1430 *
1431 * Return:		Returns status, either success or error+reason
1432 */
1433int zynqmp_pm_get_node_status(const u32 node, u32 *const status,
1434			      u32 *const requirements, u32 *const usage)
1435{
1436	u32 ret_payload[PAYLOAD_ARG_CNT];
1437	int ret;
1438
1439	if (!status || !requirements || !usage)
1440		return -EINVAL;
1441
1442	ret = zynqmp_pm_invoke_fn(PM_GET_NODE_STATUS, ret_payload, 1, node);
1443	if (ret_payload[0] == XST_PM_SUCCESS) {
1444		*status = ret_payload[1];
1445		*requirements = ret_payload[2];
1446		*usage = ret_payload[3];
1447	}
1448
1449	return ret;
1450}
1451EXPORT_SYMBOL_GPL(zynqmp_pm_get_node_status);
1452
1453/**
1454 * zynqmp_pm_force_pwrdwn - PM call to request for another PU or subsystem to
1455 *             be powered down forcefully
1456 * @node:  Node ID of the targeted PU or subsystem
1457 * @ack:   Flag to specify whether acknowledge is requested
1458 *
1459 * Return: status, either success or error+reason
1460 */
1461int zynqmp_pm_force_pwrdwn(const u32 node,
1462			   const enum zynqmp_pm_request_ack ack)
1463{
1464	return zynqmp_pm_invoke_fn(PM_FORCE_POWERDOWN, NULL, 2, node, ack);
1465}
1466EXPORT_SYMBOL_GPL(zynqmp_pm_force_pwrdwn);
1467
1468/**
1469 * zynqmp_pm_request_wake - PM call to wake up selected master or subsystem
1470 * @node:  Node ID of the master or subsystem
1471 * @set_addr:  Specifies whether the address argument is relevant
1472 * @address:   Address from which to resume when woken up
1473 * @ack:   Flag to specify whether acknowledge requested
1474 *
1475 * Return: status, either success or error+reason
1476 */
1477int zynqmp_pm_request_wake(const u32 node,
1478			   const bool set_addr,
1479			   const u64 address,
1480			   const enum zynqmp_pm_request_ack ack)
1481{
1482	/* set_addr flag is encoded into 1st bit of address */
1483	return zynqmp_pm_invoke_fn(PM_REQUEST_WAKEUP, NULL, 4, node, address | set_addr,
1484				   address >> 32, ack);
1485}
1486EXPORT_SYMBOL_GPL(zynqmp_pm_request_wake);
1487
1488/**
1489 * zynqmp_pm_set_requirement() - PM call to set requirement for PM slaves
1490 * @node:		Node ID of the slave
1491 * @capabilities:	Requested capabilities of the slave
1492 * @qos:		Quality of service (not supported)
1493 * @ack:		Flag to specify whether acknowledge is requested
1494 *
1495 * This API function is to be used for slaves a PU already has requested
1496 * to change its capabilities.
1497 *
1498 * Return: Returns status, either success or error+reason
1499 */
1500int zynqmp_pm_set_requirement(const u32 node, const u32 capabilities,
1501			      const u32 qos,
1502			      const enum zynqmp_pm_request_ack ack)
1503{
1504	return zynqmp_pm_invoke_fn(PM_SET_REQUIREMENT, NULL, 4, node, capabilities, qos, ack);
1505}
1506EXPORT_SYMBOL_GPL(zynqmp_pm_set_requirement);
1507
1508/**
1509 * zynqmp_pm_load_pdi - Load and process PDI
1510 * @src:	Source device where PDI is located
1511 * @address:	PDI src address
1512 *
1513 * This function provides support to load PDI from linux
1514 *
1515 * Return: Returns status, either success or error+reason
1516 */
1517int zynqmp_pm_load_pdi(const u32 src, const u64 address)
1518{
1519	return zynqmp_pm_invoke_fn(PM_LOAD_PDI, NULL, 3, src, lower_32_bits(address),
1520				   upper_32_bits(address));
1521}
1522EXPORT_SYMBOL_GPL(zynqmp_pm_load_pdi);
1523
1524/**
1525 * zynqmp_pm_aes_engine - Access AES hardware to encrypt/decrypt the data using
1526 * AES-GCM core.
1527 * @address:	Address of the AesParams structure.
1528 * @out:	Returned output value
1529 *
1530 * Return:	Returns status, either success or error code.
1531 */
1532int zynqmp_pm_aes_engine(const u64 address, u32 *out)
1533{
1534	u32 ret_payload[PAYLOAD_ARG_CNT];
1535	int ret;
1536
1537	if (!out)
1538		return -EINVAL;
1539
1540	ret = zynqmp_pm_invoke_fn(PM_SECURE_AES, ret_payload, 2, upper_32_bits(address),
1541				  lower_32_bits(address));
1542	*out = ret_payload[1];
1543
1544	return ret;
1545}
1546EXPORT_SYMBOL_GPL(zynqmp_pm_aes_engine);
1547
1548/**
1549 * zynqmp_pm_efuse_access - Provides access to efuse memory.
1550 * @address:	Address of the efuse params structure
1551 * @out:		Returned output value
1552 *
1553 * Return:	Returns status, either success or error code.
1554 */
1555int zynqmp_pm_efuse_access(const u64 address, u32 *out)
1556{
1557	u32 ret_payload[PAYLOAD_ARG_CNT];
1558	int ret;
1559
1560	if (!out)
1561		return -EINVAL;
1562
1563	ret = zynqmp_pm_invoke_fn(PM_EFUSE_ACCESS, ret_payload, 2,
1564				  upper_32_bits(address),
1565				  lower_32_bits(address));
1566	*out = ret_payload[1];
1567
1568	return ret;
1569}
1570EXPORT_SYMBOL_GPL(zynqmp_pm_efuse_access);
1571
1572/**
1573 * zynqmp_pm_sha_hash - Access the SHA engine to calculate the hash
1574 * @address:	Address of the data/ Address of output buffer where
1575 *		hash should be stored.
1576 * @size:	Size of the data.
1577 * @flags:
1578 *	BIT(0) - for initializing csudma driver and SHA3(Here address
1579 *		 and size inputs can be NULL).
1580 *	BIT(1) - to call Sha3_Update API which can be called multiple
1581 *		 times when data is not contiguous.
1582 *	BIT(2) - to get final hash of the whole updated data.
1583 *		 Hash will be overwritten at provided address with
1584 *		 48 bytes.
1585 *
1586 * Return:	Returns status, either success or error code.
1587 */
1588int zynqmp_pm_sha_hash(const u64 address, const u32 size, const u32 flags)
1589{
1590	u32 lower_addr = lower_32_bits(address);
1591	u32 upper_addr = upper_32_bits(address);
1592
1593	return zynqmp_pm_invoke_fn(PM_SECURE_SHA, NULL, 4, upper_addr, lower_addr, size, flags);
1594}
1595EXPORT_SYMBOL_GPL(zynqmp_pm_sha_hash);
1596
1597/**
1598 * zynqmp_pm_register_notifier() - PM API for register a subsystem
1599 *                                to be notified about specific
1600 *                                event/error.
1601 * @node:	Node ID to which the event is related.
1602 * @event:	Event Mask of Error events for which wants to get notified.
1603 * @wake:	Wake subsystem upon capturing the event if value 1
1604 * @enable:	Enable the registration for value 1, disable for value 0
1605 *
1606 * This function is used to register/un-register for particular node-event
1607 * combination in firmware.
1608 *
1609 * Return: Returns status, either success or error+reason
1610 */
1611
1612int zynqmp_pm_register_notifier(const u32 node, const u32 event,
1613				const u32 wake, const u32 enable)
1614{
1615	return zynqmp_pm_invoke_fn(PM_REGISTER_NOTIFIER, NULL, 4, node, event, wake, enable);
1616}
1617EXPORT_SYMBOL_GPL(zynqmp_pm_register_notifier);
1618
1619/**
1620 * zynqmp_pm_system_shutdown - PM call to request a system shutdown or restart
1621 * @type:	Shutdown or restart? 0 for shutdown, 1 for restart
1622 * @subtype:	Specifies which system should be restarted or shut down
1623 *
1624 * Return:	Returns status, either success or error+reason
1625 */
1626int zynqmp_pm_system_shutdown(const u32 type, const u32 subtype)
1627{
1628	return zynqmp_pm_invoke_fn(PM_SYSTEM_SHUTDOWN, NULL, 2, type, subtype);
1629}
1630
1631/**
1632 * zynqmp_pm_set_feature_config - PM call to request IOCTL for feature config
1633 * @id:         The config ID of the feature to be configured
1634 * @value:      The config value of the feature to be configured
1635 *
1636 * Return:      Returns 0 on success or error value on failure.
1637 */
1638int zynqmp_pm_set_feature_config(enum pm_feature_config_id id, u32 value)
1639{
1640	return zynqmp_pm_invoke_fn(PM_IOCTL, NULL, 4, 0, IOCTL_SET_FEATURE_CONFIG, id, value);
1641}
1642
1643/**
1644 * zynqmp_pm_get_feature_config - PM call to get value of configured feature
1645 * @id:         The config id of the feature to be queried
1646 * @payload:    Returned value array
1647 *
1648 * Return:      Returns 0 on success or error value on failure.
1649 */
1650int zynqmp_pm_get_feature_config(enum pm_feature_config_id id,
1651				 u32 *payload)
1652{
1653	return zynqmp_pm_invoke_fn(PM_IOCTL, payload, 3, 0, IOCTL_GET_FEATURE_CONFIG, id);
1654}
1655
1656/**
1657 * zynqmp_pm_sec_read_reg - PM call to securely read from given offset
1658 *		of the node
1659 * @node_id:	Node Id of the device
1660 * @offset:	Offset to be used (20-bit)
1661 * @ret_value:	Output data read from the given offset after
1662 *		firmware access policy is successfully enforced
1663 *
1664 * Return:	Returns 0 on success or error value on failure
1665 */
1666int zynqmp_pm_sec_read_reg(u32 node_id, u32 offset, u32 *ret_value)
1667{
1668	u32 ret_payload[PAYLOAD_ARG_CNT];
1669	u32 count = 1;
1670	int ret;
1671
1672	if (!ret_value)
1673		return -EINVAL;
1674
1675	ret = zynqmp_pm_invoke_fn(PM_IOCTL, ret_payload, 4, node_id, IOCTL_READ_REG,
1676				  offset, count);
1677
1678	*ret_value = ret_payload[1];
1679
1680	return ret;
1681}
1682EXPORT_SYMBOL_GPL(zynqmp_pm_sec_read_reg);
1683
1684/**
1685 * zynqmp_pm_sec_mask_write_reg - PM call to securely write to given offset
1686 *		of the node
1687 * @node_id:	Node Id of the device
1688 * @offset:	Offset to be used (20-bit)
1689 * @mask:	Mask to be used
1690 * @value:	Value to be written
1691 *
1692 * Return:	Returns 0 on success or error value on failure
1693 */
1694int zynqmp_pm_sec_mask_write_reg(const u32 node_id, const u32 offset, u32 mask,
1695				 u32 value)
1696{
1697	return zynqmp_pm_invoke_fn(PM_IOCTL, NULL, 5, node_id, IOCTL_MASK_WRITE_REG,
1698				   offset, mask, value);
1699}
1700EXPORT_SYMBOL_GPL(zynqmp_pm_sec_mask_write_reg);
1701
1702/**
1703 * zynqmp_pm_set_sd_config - PM call to set value of SD config registers
1704 * @node:	SD node ID
1705 * @config:	The config type of SD registers
1706 * @value:	Value to be set
1707 *
1708 * Return:	Returns 0 on success or error value on failure.
1709 */
1710int zynqmp_pm_set_sd_config(u32 node, enum pm_sd_config_type config, u32 value)
1711{
1712	return zynqmp_pm_invoke_fn(PM_IOCTL, NULL, 4, node, IOCTL_SET_SD_CONFIG, config, value);
1713}
1714EXPORT_SYMBOL_GPL(zynqmp_pm_set_sd_config);
1715
1716/**
1717 * zynqmp_pm_set_gem_config - PM call to set value of GEM config registers
1718 * @node:	GEM node ID
1719 * @config:	The config type of GEM registers
1720 * @value:	Value to be set
1721 *
1722 * Return:	Returns 0 on success or error value on failure.
1723 */
1724int zynqmp_pm_set_gem_config(u32 node, enum pm_gem_config_type config,
1725			     u32 value)
1726{
1727	return zynqmp_pm_invoke_fn(PM_IOCTL, NULL, 4, node, IOCTL_SET_GEM_CONFIG, config, value);
1728}
1729EXPORT_SYMBOL_GPL(zynqmp_pm_set_gem_config);
1730
1731/**
1732 * struct zynqmp_pm_shutdown_scope - Struct for shutdown scope
1733 * @subtype:	Shutdown subtype
1734 * @name:	Matching string for scope argument
1735 *
1736 * This struct encapsulates mapping between shutdown scope ID and string.
1737 */
1738struct zynqmp_pm_shutdown_scope {
1739	const enum zynqmp_pm_shutdown_subtype subtype;
1740	const char *name;
1741};
1742
1743static struct zynqmp_pm_shutdown_scope shutdown_scopes[] = {
1744	[ZYNQMP_PM_SHUTDOWN_SUBTYPE_SUBSYSTEM] = {
1745		.subtype = ZYNQMP_PM_SHUTDOWN_SUBTYPE_SUBSYSTEM,
1746		.name = "subsystem",
1747	},
1748	[ZYNQMP_PM_SHUTDOWN_SUBTYPE_PS_ONLY] = {
1749		.subtype = ZYNQMP_PM_SHUTDOWN_SUBTYPE_PS_ONLY,
1750		.name = "ps_only",
1751	},
1752	[ZYNQMP_PM_SHUTDOWN_SUBTYPE_SYSTEM] = {
1753		.subtype = ZYNQMP_PM_SHUTDOWN_SUBTYPE_SYSTEM,
1754		.name = "system",
1755	},
1756};
1757
1758static struct zynqmp_pm_shutdown_scope *selected_scope =
1759		&shutdown_scopes[ZYNQMP_PM_SHUTDOWN_SUBTYPE_SYSTEM];
1760
1761/**
1762 * zynqmp_pm_is_shutdown_scope_valid - Check if shutdown scope string is valid
1763 * @scope_string:	Shutdown scope string
1764 *
1765 * Return:		Return pointer to matching shutdown scope struct from
1766 *			array of available options in system if string is valid,
1767 *			otherwise returns NULL.
1768 */
1769static struct zynqmp_pm_shutdown_scope*
1770		zynqmp_pm_is_shutdown_scope_valid(const char *scope_string)
1771{
1772	int count;
1773
1774	for (count = 0; count < ARRAY_SIZE(shutdown_scopes); count++)
1775		if (sysfs_streq(scope_string, shutdown_scopes[count].name))
1776			return &shutdown_scopes[count];
1777
1778	return NULL;
1779}
1780
1781static ssize_t shutdown_scope_show(struct device *device,
1782				   struct device_attribute *attr,
1783				   char *buf)
1784{
1785	int i;
1786
1787	for (i = 0; i < ARRAY_SIZE(shutdown_scopes); i++) {
1788		if (&shutdown_scopes[i] == selected_scope) {
1789			strcat(buf, "[");
1790			strcat(buf, shutdown_scopes[i].name);
1791			strcat(buf, "]");
1792		} else {
1793			strcat(buf, shutdown_scopes[i].name);
1794		}
1795		strcat(buf, " ");
1796	}
1797	strcat(buf, "\n");
1798
1799	return strlen(buf);
1800}
1801
1802static ssize_t shutdown_scope_store(struct device *device,
1803				    struct device_attribute *attr,
1804				    const char *buf, size_t count)
1805{
1806	int ret;
1807	struct zynqmp_pm_shutdown_scope *scope;
1808
1809	scope = zynqmp_pm_is_shutdown_scope_valid(buf);
1810	if (!scope)
1811		return -EINVAL;
1812
1813	ret = zynqmp_pm_system_shutdown(ZYNQMP_PM_SHUTDOWN_TYPE_SETSCOPE_ONLY,
1814					scope->subtype);
1815	if (ret) {
1816		pr_err("unable to set shutdown scope %s\n", buf);
1817		return ret;
1818	}
1819
1820	selected_scope = scope;
1821
1822	return count;
1823}
1824
1825static DEVICE_ATTR_RW(shutdown_scope);
1826
1827static ssize_t health_status_store(struct device *device,
1828				   struct device_attribute *attr,
1829				   const char *buf, size_t count)
1830{
1831	int ret;
1832	unsigned int value;
1833
1834	ret = kstrtouint(buf, 10, &value);
1835	if (ret)
1836		return ret;
1837
1838	ret = zynqmp_pm_set_boot_health_status(value);
1839	if (ret) {
1840		dev_err(device, "unable to set healthy bit value to %u\n",
1841			value);
1842		return ret;
1843	}
1844
1845	return count;
1846}
1847
1848static DEVICE_ATTR_WO(health_status);
1849
1850static ssize_t ggs_show(struct device *device,
1851			struct device_attribute *attr,
1852			char *buf,
1853			u32 reg)
1854{
1855	int ret;
1856	u32 ret_payload[PAYLOAD_ARG_CNT];
1857
1858	ret = zynqmp_pm_read_ggs(reg, ret_payload);
1859	if (ret)
1860		return ret;
1861
1862	return sprintf(buf, "0x%x\n", ret_payload[1]);
1863}
1864
1865static ssize_t ggs_store(struct device *device,
1866			 struct device_attribute *attr,
1867			 const char *buf, size_t count,
1868			 u32 reg)
1869{
1870	long value;
1871	int ret;
1872
1873	if (reg >= GSS_NUM_REGS)
1874		return -EINVAL;
1875
1876	ret = kstrtol(buf, 16, &value);
1877	if (ret) {
1878		count = -EFAULT;
1879		goto err;
1880	}
1881
1882	ret = zynqmp_pm_write_ggs(reg, value);
1883	if (ret)
1884		count = -EFAULT;
1885err:
1886	return count;
1887}
1888
1889/* GGS register show functions */
1890#define GGS0_SHOW(N)						\
1891	ssize_t ggs##N##_show(struct device *device,		\
1892			      struct device_attribute *attr,	\
1893			      char *buf)			\
1894	{							\
1895		return ggs_show(device, attr, buf, N);		\
1896	}
1897
1898static GGS0_SHOW(0);
1899static GGS0_SHOW(1);
1900static GGS0_SHOW(2);
1901static GGS0_SHOW(3);
1902
1903/* GGS register store function */
1904#define GGS0_STORE(N)						\
1905	ssize_t ggs##N##_store(struct device *device,		\
1906			       struct device_attribute *attr,	\
1907			       const char *buf,			\
1908			       size_t count)			\
1909	{							\
1910		return ggs_store(device, attr, buf, count, N);	\
1911	}
1912
1913static GGS0_STORE(0);
1914static GGS0_STORE(1);
1915static GGS0_STORE(2);
1916static GGS0_STORE(3);
1917
1918static ssize_t pggs_show(struct device *device,
1919			 struct device_attribute *attr,
1920			 char *buf,
1921			 u32 reg)
1922{
1923	int ret;
1924	u32 ret_payload[PAYLOAD_ARG_CNT];
1925
1926	ret = zynqmp_pm_read_pggs(reg, ret_payload);
1927	if (ret)
1928		return ret;
1929
1930	return sprintf(buf, "0x%x\n", ret_payload[1]);
1931}
1932
1933static ssize_t pggs_store(struct device *device,
1934			  struct device_attribute *attr,
1935			  const char *buf, size_t count,
1936			  u32 reg)
1937{
1938	long value;
1939	int ret;
1940
1941	if (reg >= GSS_NUM_REGS)
1942		return -EINVAL;
1943
1944	ret = kstrtol(buf, 16, &value);
1945	if (ret) {
1946		count = -EFAULT;
1947		goto err;
1948	}
1949
1950	ret = zynqmp_pm_write_pggs(reg, value);
1951	if (ret)
1952		count = -EFAULT;
1953
1954err:
1955	return count;
1956}
1957
1958#define PGGS0_SHOW(N)						\
1959	ssize_t pggs##N##_show(struct device *device,		\
1960			       struct device_attribute *attr,	\
1961			       char *buf)			\
1962	{							\
1963		return pggs_show(device, attr, buf, N);		\
1964	}
1965
1966#define PGGS0_STORE(N)						\
1967	ssize_t pggs##N##_store(struct device *device,		\
1968				struct device_attribute *attr,	\
1969				const char *buf,		\
1970				size_t count)			\
1971	{							\
1972		return pggs_store(device, attr, buf, count, N);	\
1973	}
1974
1975/* PGGS register show functions */
1976static PGGS0_SHOW(0);
1977static PGGS0_SHOW(1);
1978static PGGS0_SHOW(2);
1979static PGGS0_SHOW(3);
1980
1981/* PGGS register store functions */
1982static PGGS0_STORE(0);
1983static PGGS0_STORE(1);
1984static PGGS0_STORE(2);
1985static PGGS0_STORE(3);
1986
1987/* GGS register attributes */
1988static DEVICE_ATTR_RW(ggs0);
1989static DEVICE_ATTR_RW(ggs1);
1990static DEVICE_ATTR_RW(ggs2);
1991static DEVICE_ATTR_RW(ggs3);
1992
1993/* PGGS register attributes */
1994static DEVICE_ATTR_RW(pggs0);
1995static DEVICE_ATTR_RW(pggs1);
1996static DEVICE_ATTR_RW(pggs2);
1997static DEVICE_ATTR_RW(pggs3);
1998
1999static ssize_t feature_config_id_show(struct device *device,
2000				      struct device_attribute *attr,
2001				      char *buf)
2002{
2003	struct zynqmp_devinfo *devinfo = dev_get_drvdata(device);
2004
2005	return sysfs_emit(buf, "%d\n", devinfo->feature_conf_id);
2006}
2007
2008static ssize_t feature_config_id_store(struct device *device,
2009				       struct device_attribute *attr,
2010				       const char *buf, size_t count)
2011{
2012	u32 config_id;
2013	int ret;
2014	struct zynqmp_devinfo *devinfo = dev_get_drvdata(device);
2015
2016	if (!buf)
2017		return -EINVAL;
2018
2019	ret = kstrtou32(buf, 10, &config_id);
2020	if (ret)
2021		return ret;
2022
2023	devinfo->feature_conf_id = config_id;
2024
2025	return count;
2026}
2027
2028static DEVICE_ATTR_RW(feature_config_id);
2029
2030static ssize_t feature_config_value_show(struct device *device,
2031					 struct device_attribute *attr,
2032					 char *buf)
2033{
2034	int ret;
2035	u32 ret_payload[PAYLOAD_ARG_CNT];
2036	struct zynqmp_devinfo *devinfo = dev_get_drvdata(device);
2037
2038	ret = zynqmp_pm_get_feature_config(devinfo->feature_conf_id,
2039					   ret_payload);
2040	if (ret)
2041		return ret;
2042
2043	return sysfs_emit(buf, "%d\n", ret_payload[1]);
2044}
2045
2046static ssize_t feature_config_value_store(struct device *device,
2047					  struct device_attribute *attr,
2048					  const char *buf, size_t count)
2049{
2050	u32 value;
2051	int ret;
2052	struct zynqmp_devinfo *devinfo = dev_get_drvdata(device);
2053
2054	if (!buf)
2055		return -EINVAL;
2056
2057	ret = kstrtou32(buf, 10, &value);
2058	if (ret)
2059		return ret;
2060
2061	ret = zynqmp_pm_set_feature_config(devinfo->feature_conf_id,
2062					   value);
2063	if (ret)
2064		return ret;
2065
2066	return count;
2067}
2068
2069static DEVICE_ATTR_RW(feature_config_value);
2070
2071static struct attribute *zynqmp_firmware_attrs[] = {
2072	&dev_attr_ggs0.attr,
2073	&dev_attr_ggs1.attr,
2074	&dev_attr_ggs2.attr,
2075	&dev_attr_ggs3.attr,
2076	&dev_attr_pggs0.attr,
2077	&dev_attr_pggs1.attr,
2078	&dev_attr_pggs2.attr,
2079	&dev_attr_pggs3.attr,
2080	&dev_attr_shutdown_scope.attr,
2081	&dev_attr_health_status.attr,
2082	&dev_attr_feature_config_id.attr,
2083	&dev_attr_feature_config_value.attr,
2084	NULL,
2085};
2086
2087ATTRIBUTE_GROUPS(zynqmp_firmware);
2088
2089static int zynqmp_firmware_probe(struct platform_device *pdev)
2090{
2091	struct device *dev = &pdev->dev;
2092	struct zynqmp_devinfo *devinfo;
2093	u32 pm_family_code;
2094	int ret;
2095
2096	ret = get_set_conduit_method(dev->of_node);
2097	if (ret)
2098		return ret;
2099
2100	/* Get platform-specific firmware data from device tree match */
2101	active_platform_fw_data = (struct platform_fw_data *)device_get_match_data(dev);
2102	if (!active_platform_fw_data)
2103		return -EINVAL;
2104
2105	/* Get SiP SVC version number */
2106	ret = zynqmp_pm_get_sip_svc_version(&sip_svc_version);
2107	if (ret)
2108		return ret;
2109
2110	ret = do_feature_check_call(PM_FEATURE_CHECK);
2111	if (ret >= 0 && ((ret & FIRMWARE_VERSION_MASK) >= PM_API_VERSION_1))
2112		feature_check_enabled = true;
2113
2114	devinfo = devm_kzalloc(dev, sizeof(*devinfo), GFP_KERNEL);
2115	if (!devinfo)
2116		return -ENOMEM;
2117
2118	devinfo->dev = dev;
2119
2120	platform_set_drvdata(pdev, devinfo);
2121
2122	/* Check PM API version number */
2123	ret = zynqmp_pm_get_api_version(&pm_api_version);
2124	if (ret)
2125		return ret;
2126
2127	if (pm_api_version < ZYNQMP_PM_VERSION) {
2128		panic("%s Platform Management API version error. Expected: v%d.%d - Found: v%d.%d\n",
2129		      __func__,
2130		      ZYNQMP_PM_VERSION_MAJOR, ZYNQMP_PM_VERSION_MINOR,
2131		      pm_api_version >> 16, pm_api_version & 0xFFFF);
2132	}
2133
2134	pr_info("%s Platform Management API v%d.%d\n", __func__,
2135		pm_api_version >> 16, pm_api_version & 0xFFFF);
2136
2137	/* Get the Family code of platform */
2138	ret = zynqmp_pm_get_family_info(&pm_family_code);
2139	if (ret < 0)
2140		return ret;
2141
2142	/* Check trustzone version number */
2143	ret = zynqmp_pm_get_trustzone_version(&pm_tz_version);
2144	if (ret)
2145		panic("Legacy trustzone found without version support\n");
2146
2147	if (pm_tz_version < ZYNQMP_TZ_VERSION)
2148		panic("%s Trustzone version error. Expected: v%d.%d - Found: v%d.%d\n",
2149		      __func__,
2150		      ZYNQMP_TZ_VERSION_MAJOR, ZYNQMP_TZ_VERSION_MINOR,
2151		      pm_tz_version >> 16, pm_tz_version & 0xFFFF);
2152
2153	pr_info("%s Trustzone version v%d.%d\n", __func__,
2154		pm_tz_version >> 16, pm_tz_version & 0xFFFF);
2155
2156	ret = mfd_add_devices(&pdev->dev, PLATFORM_DEVID_NONE, firmware_devs,
2157			      ARRAY_SIZE(firmware_devs), NULL, 0, NULL);
2158	if (ret) {
2159		dev_err(&pdev->dev, "failed to add MFD devices %d\n", ret);
2160		return ret;
2161	}
2162
2163	zynqmp_pm_api_debugfs_init();
2164
2165	if (pm_family_code != PM_ZYNQMP_FAMILY_CODE) {
2166		em_dev = platform_device_register_data(&pdev->dev, "xlnx_event_manager",
2167						       -1, NULL, 0);
2168		if (IS_ERR(em_dev))
2169			dev_err_probe(&pdev->dev, PTR_ERR(em_dev), "EM register fail with error\n");
2170	}
2171
2172	return of_platform_populate(dev->of_node, NULL, NULL, dev);
2173}
2174
2175static void zynqmp_firmware_remove(struct platform_device *pdev)
2176{
2177	struct pm_api_feature_data *feature_data;
2178	struct hlist_node *tmp;
2179	int i;
2180
2181	mfd_remove_devices(&pdev->dev);
2182	zynqmp_pm_api_debugfs_exit();
2183
2184	hash_for_each_safe(pm_api_features_map, i, tmp, feature_data, hentry) {
2185		hash_del(&feature_data->hentry);
2186		kfree(feature_data);
2187	}
2188
2189	platform_device_unregister(em_dev);
2190}
2191
2192static void zynqmp_firmware_sync_state(struct device *dev)
2193{
2194	struct device_node *np = dev->of_node;
2195
2196	if (!of_device_is_compatible(np, "xlnx,zynqmp-firmware"))
2197		return;
2198
2199	of_genpd_sync_state(np);
2200
2201	if (zynqmp_pm_init_finalize())
2202		dev_warn(dev, "failed to release power management to firmware\n");
2203}
2204
2205static const struct platform_fw_data platform_fw_data_versal = {
2206	.family_code = PM_VERSAL_FAMILY_CODE,
2207};
2208
2209static const struct platform_fw_data platform_fw_data_versal_net = {
2210	.family_code = PM_VERSAL_NET_FAMILY_CODE,
2211};
2212
2213static const struct platform_fw_data platform_fw_data_zynqmp = {
2214	.family_code = PM_ZYNQMP_FAMILY_CODE,
2215};
2216
2217static const struct of_device_id zynqmp_firmware_of_match[] = {
2218	{.compatible = "xlnx,zynqmp-firmware", .data = &platform_fw_data_zynqmp},
2219	{.compatible = "xlnx,versal-firmware", .data = &platform_fw_data_versal},
2220	{.compatible = "xlnx,versal-net-firmware", .data = &platform_fw_data_versal_net},
2221	{},
2222};
2223MODULE_DEVICE_TABLE(of, zynqmp_firmware_of_match);
2224
2225static struct platform_driver zynqmp_firmware_driver = {
2226	.driver = {
2227		.name = "zynqmp_firmware",
2228		.of_match_table = zynqmp_firmware_of_match,
2229		.dev_groups = zynqmp_firmware_groups,
2230		.sync_state = zynqmp_firmware_sync_state,
2231	},
2232	.probe = zynqmp_firmware_probe,
2233	.remove = zynqmp_firmware_remove,
2234};
2235module_platform_driver(zynqmp_firmware_driver);
~/ Read-only file preview.