Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

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