176582671SRajan Vaja // SPDX-License-Identifier: GPL-2.0 276582671SRajan Vaja /* 376582671SRajan Vaja * Xilinx Zynq MPSoC Firmware layer 476582671SRajan Vaja * 5f1f21becSTejas Patel * Copyright (C) 2014-2021 Xilinx, Inc. 676582671SRajan Vaja * 776582671SRajan Vaja * Michal Simek <michal.simek@xilinx.com> 876582671SRajan Vaja * Davorin Mista <davorin.mista@aggios.com> 976582671SRajan Vaja * Jolly Shah <jollys@xilinx.com> 1076582671SRajan Vaja * Rajan Vaja <rajanv@xilinx.com> 1176582671SRajan Vaja */ 1276582671SRajan Vaja 1376582671SRajan Vaja #include <linux/arm-smccc.h> 1476582671SRajan Vaja #include <linux/compiler.h> 1576582671SRajan Vaja #include <linux/device.h> 1676582671SRajan Vaja #include <linux/init.h> 17e23d9c6dSJolly Shah #include <linux/mfd/core.h> 1876582671SRajan Vaja #include <linux/module.h> 1976582671SRajan Vaja #include <linux/of.h> 2076582671SRajan Vaja #include <linux/of_platform.h> 2176582671SRajan Vaja #include <linux/slab.h> 2276582671SRajan Vaja #include <linux/uaccess.h> 23acfdd185SAmit Sunil Dhamne #include <linux/hashtable.h> 2476582671SRajan Vaja 2576582671SRajan Vaja #include <linux/firmware/xlnx-zynqmp.h> 26a515814eSAbhyuday Godhasara #include <linux/firmware/xlnx-event-manager.h> 27b3217252SRajan Vaja #include "zynqmp-debug.h" 2876582671SRajan Vaja 29acfdd185SAmit Sunil Dhamne /* Max HashMap Order for PM API feature check (1<<7 = 128) */ 30acfdd185SAmit Sunil Dhamne #define PM_API_FEATURE_CHECK_MAX_ORDER 7 31acfdd185SAmit Sunil Dhamne 3223c64d76SPiyush Mehta /* CRL registers and bitfields */ 3323c64d76SPiyush Mehta #define CRL_APB_BASE 0xFF5E0000U 3423c64d76SPiyush Mehta /* BOOT_PIN_CTRL- Used to control the mode pins after boot */ 3523c64d76SPiyush Mehta #define CRL_APB_BOOT_PIN_CTRL (CRL_APB_BASE + (0x250U)) 3623c64d76SPiyush Mehta /* BOOT_PIN_CTRL_MASK- out_val[11:8], out_en[3:0] */ 3723c64d76SPiyush Mehta #define CRL_APB_BOOTPIN_CTRL_MASK 0xF0FU 3823c64d76SPiyush Mehta 39461011b1SRavi Patel static bool feature_check_enabled; 4069fe24d1SZou Wei static DEFINE_HASHTABLE(pm_api_features_map, PM_API_FEATURE_CHECK_MAX_ORDER); 41acfdd185SAmit Sunil Dhamne 42a515814eSAbhyuday Godhasara static struct platform_device *em_dev; 43a515814eSAbhyuday Godhasara 44acfdd185SAmit Sunil Dhamne /** 45acfdd185SAmit Sunil Dhamne * struct pm_api_feature_data - PM API Feature data 46acfdd185SAmit Sunil Dhamne * @pm_api_id: PM API Id, used as key to index into hashmap 47acfdd185SAmit Sunil Dhamne * @feature_status: status of PM API feature: valid, invalid 48acfdd185SAmit Sunil Dhamne * @hentry: hlist_node that hooks this entry into hashtable 49acfdd185SAmit Sunil Dhamne */ 50acfdd185SAmit Sunil Dhamne struct pm_api_feature_data { 51acfdd185SAmit Sunil Dhamne u32 pm_api_id; 52acfdd185SAmit Sunil Dhamne int feature_status; 53acfdd185SAmit Sunil Dhamne struct hlist_node hentry; 54acfdd185SAmit Sunil Dhamne }; 55461011b1SRavi Patel 56e23d9c6dSJolly Shah static const struct mfd_cell firmware_devs[] = { 57e23d9c6dSJolly Shah { 58e23d9c6dSJolly Shah .name = "zynqmp_power_controller", 59e23d9c6dSJolly Shah }, 60e23d9c6dSJolly Shah }; 61e23d9c6dSJolly Shah 6276582671SRajan Vaja /** 6376582671SRajan Vaja * zynqmp_pm_ret_code() - Convert PMU-FW error codes to Linux error codes 6476582671SRajan Vaja * @ret_status: PMUFW return code 6576582671SRajan Vaja * 6676582671SRajan Vaja * Return: corresponding Linux error code 6776582671SRajan Vaja */ 6876582671SRajan Vaja static int zynqmp_pm_ret_code(u32 ret_status) 6976582671SRajan Vaja { 7076582671SRajan Vaja switch (ret_status) { 7176582671SRajan Vaja case XST_PM_SUCCESS: 7276582671SRajan Vaja case XST_PM_DOUBLE_REQ: 7376582671SRajan Vaja return 0; 74461011b1SRavi Patel case XST_PM_NO_FEATURE: 75461011b1SRavi Patel return -ENOTSUPP; 7676582671SRajan Vaja case XST_PM_NO_ACCESS: 7776582671SRajan Vaja return -EACCES; 7876582671SRajan Vaja case XST_PM_ABORT_SUSPEND: 7976582671SRajan Vaja return -ECANCELED; 80df2a4d94SRajan Vaja case XST_PM_MULT_USER: 81df2a4d94SRajan Vaja return -EUSERS; 8276582671SRajan Vaja case XST_PM_INTERNAL: 8376582671SRajan Vaja case XST_PM_CONFLICT: 8476582671SRajan Vaja case XST_PM_INVALID_NODE: 8576582671SRajan Vaja default: 8676582671SRajan Vaja return -EINVAL; 8776582671SRajan Vaja } 8876582671SRajan Vaja } 8976582671SRajan Vaja 9076582671SRajan Vaja static noinline int do_fw_call_fail(u64 arg0, u64 arg1, u64 arg2, 9176582671SRajan Vaja u32 *ret_payload) 9276582671SRajan Vaja { 9376582671SRajan Vaja return -ENODEV; 9476582671SRajan Vaja } 9576582671SRajan Vaja 9676582671SRajan Vaja /* 9776582671SRajan Vaja * PM function call wrapper 9876582671SRajan Vaja * Invoke do_fw_call_smc or do_fw_call_hvc, depending on the configuration 9976582671SRajan Vaja */ 10076582671SRajan Vaja static int (*do_fw_call)(u64, u64, u64, u32 *ret_payload) = do_fw_call_fail; 10176582671SRajan Vaja 10276582671SRajan Vaja /** 10376582671SRajan Vaja * do_fw_call_smc() - Call system-level platform management layer (SMC) 10476582671SRajan Vaja * @arg0: Argument 0 to SMC call 10576582671SRajan Vaja * @arg1: Argument 1 to SMC call 10676582671SRajan Vaja * @arg2: Argument 2 to SMC call 10776582671SRajan Vaja * @ret_payload: Returned value array 10876582671SRajan Vaja * 10976582671SRajan Vaja * Invoke platform management function via SMC call (no hypervisor present). 11076582671SRajan Vaja * 11176582671SRajan Vaja * Return: Returns status, either success or error+reason 11276582671SRajan Vaja */ 11376582671SRajan Vaja static noinline int do_fw_call_smc(u64 arg0, u64 arg1, u64 arg2, 11476582671SRajan Vaja u32 *ret_payload) 11576582671SRajan Vaja { 11676582671SRajan Vaja struct arm_smccc_res res; 11776582671SRajan Vaja 11876582671SRajan Vaja arm_smccc_smc(arg0, arg1, arg2, 0, 0, 0, 0, 0, &res); 11976582671SRajan Vaja 12076582671SRajan Vaja if (ret_payload) { 12176582671SRajan Vaja ret_payload[0] = lower_32_bits(res.a0); 12276582671SRajan Vaja ret_payload[1] = upper_32_bits(res.a0); 12376582671SRajan Vaja ret_payload[2] = lower_32_bits(res.a1); 12476582671SRajan Vaja ret_payload[3] = upper_32_bits(res.a1); 12576582671SRajan Vaja } 12676582671SRajan Vaja 12776582671SRajan Vaja return zynqmp_pm_ret_code((enum pm_ret_status)res.a0); 12876582671SRajan Vaja } 12976582671SRajan Vaja 13076582671SRajan Vaja /** 13176582671SRajan Vaja * do_fw_call_hvc() - Call system-level platform management layer (HVC) 13276582671SRajan Vaja * @arg0: Argument 0 to HVC call 13376582671SRajan Vaja * @arg1: Argument 1 to HVC call 13476582671SRajan Vaja * @arg2: Argument 2 to HVC call 13576582671SRajan Vaja * @ret_payload: Returned value array 13676582671SRajan Vaja * 13776582671SRajan Vaja * Invoke platform management function via HVC 13876582671SRajan Vaja * HVC-based for communication through hypervisor 13976582671SRajan Vaja * (no direct communication with ATF). 14076582671SRajan Vaja * 14176582671SRajan Vaja * Return: Returns status, either success or error+reason 14276582671SRajan Vaja */ 14376582671SRajan Vaja static noinline int do_fw_call_hvc(u64 arg0, u64 arg1, u64 arg2, 14476582671SRajan Vaja u32 *ret_payload) 14576582671SRajan Vaja { 14676582671SRajan Vaja struct arm_smccc_res res; 14776582671SRajan Vaja 14876582671SRajan Vaja arm_smccc_hvc(arg0, arg1, arg2, 0, 0, 0, 0, 0, &res); 14976582671SRajan Vaja 15076582671SRajan Vaja if (ret_payload) { 15176582671SRajan Vaja ret_payload[0] = lower_32_bits(res.a0); 15276582671SRajan Vaja ret_payload[1] = upper_32_bits(res.a0); 15376582671SRajan Vaja ret_payload[2] = lower_32_bits(res.a1); 15476582671SRajan Vaja ret_payload[3] = upper_32_bits(res.a1); 15576582671SRajan Vaja } 15676582671SRajan Vaja 15776582671SRajan Vaja return zynqmp_pm_ret_code((enum pm_ret_status)res.a0); 15876582671SRajan Vaja } 15976582671SRajan Vaja 16076582671SRajan Vaja /** 161461011b1SRavi Patel * zynqmp_pm_feature() - Check weather given feature is supported or not 162461011b1SRavi Patel * @api_id: API ID to check 163461011b1SRavi Patel * 164461011b1SRavi Patel * Return: Returns status, either success or error+reason 165461011b1SRavi Patel */ 166f4d77525SAbhyuday Godhasara int zynqmp_pm_feature(const u32 api_id) 167461011b1SRavi Patel { 168461011b1SRavi Patel int ret; 169461011b1SRavi Patel u32 ret_payload[PAYLOAD_ARG_CNT]; 170461011b1SRavi Patel u64 smc_arg[2]; 171acfdd185SAmit Sunil Dhamne struct pm_api_feature_data *feature_data; 172461011b1SRavi Patel 173461011b1SRavi Patel if (!feature_check_enabled) 174461011b1SRavi Patel return 0; 175461011b1SRavi Patel 176acfdd185SAmit Sunil Dhamne /* Check for existing entry in hash table for given api */ 177acfdd185SAmit Sunil Dhamne hash_for_each_possible(pm_api_features_map, feature_data, hentry, 178acfdd185SAmit Sunil Dhamne api_id) { 179acfdd185SAmit Sunil Dhamne if (feature_data->pm_api_id == api_id) 180acfdd185SAmit Sunil Dhamne return feature_data->feature_status; 181acfdd185SAmit Sunil Dhamne } 182f3217d6fSArnd Bergmann 183acfdd185SAmit Sunil Dhamne /* Add new entry if not present */ 184acfdd185SAmit Sunil Dhamne feature_data = kmalloc(sizeof(*feature_data), GFP_KERNEL); 185acfdd185SAmit Sunil Dhamne if (!feature_data) 186acfdd185SAmit Sunil Dhamne return -ENOMEM; 187461011b1SRavi Patel 188acfdd185SAmit Sunil Dhamne feature_data->pm_api_id = api_id; 189461011b1SRavi Patel smc_arg[0] = PM_SIP_SVC | PM_FEATURE_CHECK; 190461011b1SRavi Patel smc_arg[1] = api_id; 191461011b1SRavi Patel 192461011b1SRavi Patel ret = do_fw_call(smc_arg[0], smc_arg[1], 0, ret_payload); 193acfdd185SAmit Sunil Dhamne if (ret) 194acfdd185SAmit Sunil Dhamne ret = -EOPNOTSUPP; 195acfdd185SAmit Sunil Dhamne else 196acfdd185SAmit Sunil Dhamne ret = ret_payload[1]; 197461011b1SRavi Patel 198acfdd185SAmit Sunil Dhamne feature_data->feature_status = ret; 199acfdd185SAmit Sunil Dhamne hash_add(pm_api_features_map, &feature_data->hentry, api_id); 200461011b1SRavi Patel 201acfdd185SAmit Sunil Dhamne return ret; 202461011b1SRavi Patel } 203f4d77525SAbhyuday Godhasara EXPORT_SYMBOL_GPL(zynqmp_pm_feature); 204461011b1SRavi Patel 205461011b1SRavi Patel /** 20676582671SRajan Vaja * zynqmp_pm_invoke_fn() - Invoke the system-level platform management layer 20776582671SRajan Vaja * caller function depending on the configuration 20876582671SRajan Vaja * @pm_api_id: Requested PM-API call 20976582671SRajan Vaja * @arg0: Argument 0 to requested PM-API call 21076582671SRajan Vaja * @arg1: Argument 1 to requested PM-API call 21176582671SRajan Vaja * @arg2: Argument 2 to requested PM-API call 21276582671SRajan Vaja * @arg3: Argument 3 to requested PM-API call 21376582671SRajan Vaja * @ret_payload: Returned value array 21476582671SRajan Vaja * 21576582671SRajan Vaja * Invoke platform management function for SMC or HVC call, depending on 21676582671SRajan Vaja * configuration. 21776582671SRajan Vaja * Following SMC Calling Convention (SMCCC) for SMC64: 21876582671SRajan Vaja * Pm Function Identifier, 21976582671SRajan Vaja * PM_SIP_SVC + PM_API_ID = 22076582671SRajan Vaja * ((SMC_TYPE_FAST << FUNCID_TYPE_SHIFT) 22176582671SRajan Vaja * ((SMC_64) << FUNCID_CC_SHIFT) 22276582671SRajan Vaja * ((SIP_START) << FUNCID_OEN_SHIFT) 22376582671SRajan Vaja * ((PM_API_ID) & FUNCID_NUM_MASK)) 22476582671SRajan Vaja * 22576582671SRajan Vaja * PM_SIP_SVC - Registered ZynqMP SIP Service Call. 22676582671SRajan Vaja * PM_API_ID - Platform Management API ID. 22776582671SRajan Vaja * 22876582671SRajan Vaja * Return: Returns status, either success or error+reason 22976582671SRajan Vaja */ 23076582671SRajan Vaja int zynqmp_pm_invoke_fn(u32 pm_api_id, u32 arg0, u32 arg1, 23176582671SRajan Vaja u32 arg2, u32 arg3, u32 *ret_payload) 23276582671SRajan Vaja { 23376582671SRajan Vaja /* 23476582671SRajan Vaja * Added SIP service call Function Identifier 23576582671SRajan Vaja * Make sure to stay in x0 register 23676582671SRajan Vaja */ 23776582671SRajan Vaja u64 smc_arg[4]; 238acfdd185SAmit Sunil Dhamne int ret; 23976582671SRajan Vaja 240acfdd185SAmit Sunil Dhamne /* Check if feature is supported or not */ 241acfdd185SAmit Sunil Dhamne ret = zynqmp_pm_feature(pm_api_id); 242acfdd185SAmit Sunil Dhamne if (ret < 0) 243acfdd185SAmit Sunil Dhamne return ret; 244461011b1SRavi Patel 24576582671SRajan Vaja smc_arg[0] = PM_SIP_SVC | pm_api_id; 24676582671SRajan Vaja smc_arg[1] = ((u64)arg1 << 32) | arg0; 24776582671SRajan Vaja smc_arg[2] = ((u64)arg3 << 32) | arg2; 24876582671SRajan Vaja 24976582671SRajan Vaja return do_fw_call(smc_arg[0], smc_arg[1], smc_arg[2], ret_payload); 25076582671SRajan Vaja } 25176582671SRajan Vaja 25276582671SRajan Vaja static u32 pm_api_version; 25376582671SRajan Vaja static u32 pm_tz_version; 25476582671SRajan Vaja 25576582671SRajan Vaja /** 25676582671SRajan Vaja * zynqmp_pm_get_api_version() - Get version number of PMU PM firmware 25776582671SRajan Vaja * @version: Returned version value 25876582671SRajan Vaja * 25976582671SRajan Vaja * Return: Returns status, either success or error+reason 26076582671SRajan Vaja */ 261b9b3a8beSRajan Vaja int zynqmp_pm_get_api_version(u32 *version) 26276582671SRajan Vaja { 26376582671SRajan Vaja u32 ret_payload[PAYLOAD_ARG_CNT]; 26476582671SRajan Vaja int ret; 26576582671SRajan Vaja 26676582671SRajan Vaja if (!version) 26776582671SRajan Vaja return -EINVAL; 26876582671SRajan Vaja 26976582671SRajan Vaja /* Check is PM API version already verified */ 27076582671SRajan Vaja if (pm_api_version > 0) { 27176582671SRajan Vaja *version = pm_api_version; 27276582671SRajan Vaja return 0; 27376582671SRajan Vaja } 27476582671SRajan Vaja ret = zynqmp_pm_invoke_fn(PM_GET_API_VERSION, 0, 0, 0, 0, ret_payload); 27576582671SRajan Vaja *version = ret_payload[1]; 27676582671SRajan Vaja 27776582671SRajan Vaja return ret; 27876582671SRajan Vaja } 279b9b3a8beSRajan Vaja EXPORT_SYMBOL_GPL(zynqmp_pm_get_api_version); 28076582671SRajan Vaja 28176582671SRajan Vaja /** 282fe6f42cfSNava kishore Manne * zynqmp_pm_get_chipid - Get silicon ID registers 283fe6f42cfSNava kishore Manne * @idcode: IDCODE register 284fe6f42cfSNava kishore Manne * @version: version register 285fe6f42cfSNava kishore Manne * 286fe6f42cfSNava kishore Manne * Return: Returns the status of the operation and the idcode and version 287fe6f42cfSNava kishore Manne * registers in @idcode and @version. 288fe6f42cfSNava kishore Manne */ 28921cd93baSRajan Vaja int zynqmp_pm_get_chipid(u32 *idcode, u32 *version) 290fe6f42cfSNava kishore Manne { 291fe6f42cfSNava kishore Manne u32 ret_payload[PAYLOAD_ARG_CNT]; 292fe6f42cfSNava kishore Manne int ret; 293fe6f42cfSNava kishore Manne 294fe6f42cfSNava kishore Manne if (!idcode || !version) 295fe6f42cfSNava kishore Manne return -EINVAL; 296fe6f42cfSNava kishore Manne 297fe6f42cfSNava kishore Manne ret = zynqmp_pm_invoke_fn(PM_GET_CHIPID, 0, 0, 0, 0, ret_payload); 298fe6f42cfSNava kishore Manne *idcode = ret_payload[1]; 299fe6f42cfSNava kishore Manne *version = ret_payload[2]; 300fe6f42cfSNava kishore Manne 301fe6f42cfSNava kishore Manne return ret; 302fe6f42cfSNava kishore Manne } 30321cd93baSRajan Vaja EXPORT_SYMBOL_GPL(zynqmp_pm_get_chipid); 304fe6f42cfSNava kishore Manne 305fe6f42cfSNava kishore Manne /** 30676582671SRajan Vaja * zynqmp_pm_get_trustzone_version() - Get secure trustzone firmware version 30776582671SRajan Vaja * @version: Returned version value 30876582671SRajan Vaja * 30976582671SRajan Vaja * Return: Returns status, either success or error+reason 31076582671SRajan Vaja */ 31176582671SRajan Vaja static int zynqmp_pm_get_trustzone_version(u32 *version) 31276582671SRajan Vaja { 31376582671SRajan Vaja u32 ret_payload[PAYLOAD_ARG_CNT]; 31476582671SRajan Vaja int ret; 31576582671SRajan Vaja 31676582671SRajan Vaja if (!version) 31776582671SRajan Vaja return -EINVAL; 31876582671SRajan Vaja 31976582671SRajan Vaja /* Check is PM trustzone version already verified */ 32076582671SRajan Vaja if (pm_tz_version > 0) { 32176582671SRajan Vaja *version = pm_tz_version; 32276582671SRajan Vaja return 0; 32376582671SRajan Vaja } 32476582671SRajan Vaja ret = zynqmp_pm_invoke_fn(PM_GET_TRUSTZONE_VERSION, 0, 0, 32576582671SRajan Vaja 0, 0, ret_payload); 32676582671SRajan Vaja *version = ret_payload[1]; 32776582671SRajan Vaja 32876582671SRajan Vaja return ret; 32976582671SRajan Vaja } 33076582671SRajan Vaja 33176582671SRajan Vaja /** 33276582671SRajan Vaja * get_set_conduit_method() - Choose SMC or HVC based communication 33376582671SRajan Vaja * @np: Pointer to the device_node structure 33476582671SRajan Vaja * 33576582671SRajan Vaja * Use SMC or HVC-based functions to communicate with EL2/EL3. 33676582671SRajan Vaja * 33776582671SRajan Vaja * Return: Returns 0 on success or error code 33876582671SRajan Vaja */ 33976582671SRajan Vaja static int get_set_conduit_method(struct device_node *np) 34076582671SRajan Vaja { 34176582671SRajan Vaja const char *method; 34276582671SRajan Vaja 34376582671SRajan Vaja if (of_property_read_string(np, "method", &method)) { 34476582671SRajan Vaja pr_warn("%s missing \"method\" property\n", __func__); 34576582671SRajan Vaja return -ENXIO; 34676582671SRajan Vaja } 34776582671SRajan Vaja 34876582671SRajan Vaja if (!strcmp("hvc", method)) { 34976582671SRajan Vaja do_fw_call = do_fw_call_hvc; 35076582671SRajan Vaja } else if (!strcmp("smc", method)) { 35176582671SRajan Vaja do_fw_call = do_fw_call_smc; 35276582671SRajan Vaja } else { 35376582671SRajan Vaja pr_warn("%s Invalid \"method\" property: %s\n", 35476582671SRajan Vaja __func__, method); 35576582671SRajan Vaja return -EINVAL; 35676582671SRajan Vaja } 35776582671SRajan Vaja 35876582671SRajan Vaja return 0; 35976582671SRajan Vaja } 36076582671SRajan Vaja 36159ecdd77SRajan Vaja /** 36259ecdd77SRajan Vaja * zynqmp_pm_query_data() - Get query data from firmware 36359ecdd77SRajan Vaja * @qdata: Variable to the zynqmp_pm_query_data structure 36459ecdd77SRajan Vaja * @out: Returned output value 36559ecdd77SRajan Vaja * 36659ecdd77SRajan Vaja * Return: Returns status, either success or error+reason 36759ecdd77SRajan Vaja */ 3686366c1baSRajan Vaja int zynqmp_pm_query_data(struct zynqmp_pm_query_data qdata, u32 *out) 36959ecdd77SRajan Vaja { 370f9627312SRajan Vaja int ret; 371f9627312SRajan Vaja 372f9627312SRajan Vaja ret = zynqmp_pm_invoke_fn(PM_QUERY_DATA, qdata.qid, qdata.arg1, 37359ecdd77SRajan Vaja qdata.arg2, qdata.arg3, out); 374f9627312SRajan Vaja 375f9627312SRajan Vaja /* 376f9627312SRajan Vaja * For clock name query, all bytes in SMC response are clock name 377f9627312SRajan Vaja * characters and return code is always success. For invalid clocks, 378f9627312SRajan Vaja * clock name bytes would be zeros. 379f9627312SRajan Vaja */ 380f9627312SRajan Vaja return qdata.qid == PM_QID_CLOCK_GET_NAME ? 0 : ret; 381f9627312SRajan Vaja } 3826366c1baSRajan Vaja EXPORT_SYMBOL_GPL(zynqmp_pm_query_data); 383f9627312SRajan Vaja 384f9627312SRajan Vaja /** 385f9627312SRajan Vaja * zynqmp_pm_clock_enable() - Enable the clock for given id 386f9627312SRajan Vaja * @clock_id: ID of the clock to be enabled 387f9627312SRajan Vaja * 388f9627312SRajan Vaja * This function is used by master to enable the clock 389f9627312SRajan Vaja * including peripherals and PLL clocks. 390f9627312SRajan Vaja * 391f9627312SRajan Vaja * Return: Returns status, either success or error+reason 392f9627312SRajan Vaja */ 3933637e84cSRajan Vaja int zynqmp_pm_clock_enable(u32 clock_id) 394f9627312SRajan Vaja { 395f9627312SRajan Vaja return zynqmp_pm_invoke_fn(PM_CLOCK_ENABLE, clock_id, 0, 0, 0, NULL); 396f9627312SRajan Vaja } 3973637e84cSRajan Vaja EXPORT_SYMBOL_GPL(zynqmp_pm_clock_enable); 398f9627312SRajan Vaja 399f9627312SRajan Vaja /** 400f9627312SRajan Vaja * zynqmp_pm_clock_disable() - Disable the clock for given id 401f9627312SRajan Vaja * @clock_id: ID of the clock to be disable 402f9627312SRajan Vaja * 403f9627312SRajan Vaja * This function is used by master to disable the clock 404f9627312SRajan Vaja * including peripherals and PLL clocks. 405f9627312SRajan Vaja * 406f9627312SRajan Vaja * Return: Returns status, either success or error+reason 407f9627312SRajan Vaja */ 408f5ccd54bSRajan Vaja int zynqmp_pm_clock_disable(u32 clock_id) 409f9627312SRajan Vaja { 410f9627312SRajan Vaja return zynqmp_pm_invoke_fn(PM_CLOCK_DISABLE, clock_id, 0, 0, 0, NULL); 411f9627312SRajan Vaja } 412f5ccd54bSRajan Vaja EXPORT_SYMBOL_GPL(zynqmp_pm_clock_disable); 413f9627312SRajan Vaja 414f9627312SRajan Vaja /** 415f9627312SRajan Vaja * zynqmp_pm_clock_getstate() - Get the clock state for given id 416f9627312SRajan Vaja * @clock_id: ID of the clock to be queried 417f9627312SRajan Vaja * @state: 1/0 (Enabled/Disabled) 418f9627312SRajan Vaja * 419f9627312SRajan Vaja * This function is used by master to get the state of clock 420f9627312SRajan Vaja * including peripherals and PLL clocks. 421f9627312SRajan Vaja * 422f9627312SRajan Vaja * Return: Returns status, either success or error+reason 423f9627312SRajan Vaja */ 4245e76731dSRajan Vaja int zynqmp_pm_clock_getstate(u32 clock_id, u32 *state) 425f9627312SRajan Vaja { 426f9627312SRajan Vaja u32 ret_payload[PAYLOAD_ARG_CNT]; 427f9627312SRajan Vaja int ret; 428f9627312SRajan Vaja 429f9627312SRajan Vaja ret = zynqmp_pm_invoke_fn(PM_CLOCK_GETSTATE, clock_id, 0, 430f9627312SRajan Vaja 0, 0, ret_payload); 431f9627312SRajan Vaja *state = ret_payload[1]; 432f9627312SRajan Vaja 433f9627312SRajan Vaja return ret; 434f9627312SRajan Vaja } 4355e76731dSRajan Vaja EXPORT_SYMBOL_GPL(zynqmp_pm_clock_getstate); 436f9627312SRajan Vaja 437f9627312SRajan Vaja /** 438f9627312SRajan Vaja * zynqmp_pm_clock_setdivider() - Set the clock divider for given id 439f9627312SRajan Vaja * @clock_id: ID of the clock 440f9627312SRajan Vaja * @divider: divider value 441f9627312SRajan Vaja * 442f9627312SRajan Vaja * This function is used by master to set divider for any clock 443f9627312SRajan Vaja * to achieve desired rate. 444f9627312SRajan Vaja * 445f9627312SRajan Vaja * Return: Returns status, either success or error+reason 446f9627312SRajan Vaja */ 447fc9fb8fbSRajan Vaja int zynqmp_pm_clock_setdivider(u32 clock_id, u32 divider) 448f9627312SRajan Vaja { 449f9627312SRajan Vaja return zynqmp_pm_invoke_fn(PM_CLOCK_SETDIVIDER, clock_id, divider, 450f9627312SRajan Vaja 0, 0, NULL); 451f9627312SRajan Vaja } 452fc9fb8fbSRajan Vaja EXPORT_SYMBOL_GPL(zynqmp_pm_clock_setdivider); 453f9627312SRajan Vaja 454f9627312SRajan Vaja /** 455f9627312SRajan Vaja * zynqmp_pm_clock_getdivider() - Get the clock divider for given id 456f9627312SRajan Vaja * @clock_id: ID of the clock 457f9627312SRajan Vaja * @divider: divider value 458f9627312SRajan Vaja * 459f9627312SRajan Vaja * This function is used by master to get divider values 460f9627312SRajan Vaja * for any clock. 461f9627312SRajan Vaja * 462f9627312SRajan Vaja * Return: Returns status, either success or error+reason 463f9627312SRajan Vaja */ 4640667a8d1SRajan Vaja int zynqmp_pm_clock_getdivider(u32 clock_id, u32 *divider) 465f9627312SRajan Vaja { 466f9627312SRajan Vaja u32 ret_payload[PAYLOAD_ARG_CNT]; 467f9627312SRajan Vaja int ret; 468f9627312SRajan Vaja 469f9627312SRajan Vaja ret = zynqmp_pm_invoke_fn(PM_CLOCK_GETDIVIDER, clock_id, 0, 470f9627312SRajan Vaja 0, 0, ret_payload); 471f9627312SRajan Vaja *divider = ret_payload[1]; 472f9627312SRajan Vaja 473f9627312SRajan Vaja return ret; 474f9627312SRajan Vaja } 4750667a8d1SRajan Vaja EXPORT_SYMBOL_GPL(zynqmp_pm_clock_getdivider); 476f9627312SRajan Vaja 477f9627312SRajan Vaja /** 478f9627312SRajan Vaja * zynqmp_pm_clock_setrate() - Set the clock rate for given id 479f9627312SRajan Vaja * @clock_id: ID of the clock 480f9627312SRajan Vaja * @rate: rate value in hz 481f9627312SRajan Vaja * 482f9627312SRajan Vaja * This function is used by master to set rate for any clock. 483f9627312SRajan Vaja * 484f9627312SRajan Vaja * Return: Returns status, either success or error+reason 485f9627312SRajan Vaja */ 4867a1e1062SRajan Vaja int zynqmp_pm_clock_setrate(u32 clock_id, u64 rate) 487f9627312SRajan Vaja { 488f9627312SRajan Vaja return zynqmp_pm_invoke_fn(PM_CLOCK_SETRATE, clock_id, 489f9627312SRajan Vaja lower_32_bits(rate), 490f9627312SRajan Vaja upper_32_bits(rate), 491f9627312SRajan Vaja 0, NULL); 492f9627312SRajan Vaja } 4937a1e1062SRajan Vaja EXPORT_SYMBOL_GPL(zynqmp_pm_clock_setrate); 494f9627312SRajan Vaja 495f9627312SRajan Vaja /** 496f9627312SRajan Vaja * zynqmp_pm_clock_getrate() - Get the clock rate for given id 497f9627312SRajan Vaja * @clock_id: ID of the clock 498f9627312SRajan Vaja * @rate: rate value in hz 499f9627312SRajan Vaja * 500f9627312SRajan Vaja * This function is used by master to get rate 501f9627312SRajan Vaja * for any clock. 502f9627312SRajan Vaja * 503f9627312SRajan Vaja * Return: Returns status, either success or error+reason 504f9627312SRajan Vaja */ 5057a1e1062SRajan Vaja int zynqmp_pm_clock_getrate(u32 clock_id, u64 *rate) 506f9627312SRajan Vaja { 507f9627312SRajan Vaja u32 ret_payload[PAYLOAD_ARG_CNT]; 508f9627312SRajan Vaja int ret; 509f9627312SRajan Vaja 510f9627312SRajan Vaja ret = zynqmp_pm_invoke_fn(PM_CLOCK_GETRATE, clock_id, 0, 511f9627312SRajan Vaja 0, 0, ret_payload); 512f9627312SRajan Vaja *rate = ((u64)ret_payload[2] << 32) | ret_payload[1]; 513f9627312SRajan Vaja 514f9627312SRajan Vaja return ret; 515f9627312SRajan Vaja } 5167a1e1062SRajan Vaja EXPORT_SYMBOL_GPL(zynqmp_pm_clock_getrate); 517f9627312SRajan Vaja 518f9627312SRajan Vaja /** 519f9627312SRajan Vaja * zynqmp_pm_clock_setparent() - Set the clock parent for given id 520f9627312SRajan Vaja * @clock_id: ID of the clock 521f9627312SRajan Vaja * @parent_id: parent id 522f9627312SRajan Vaja * 523f9627312SRajan Vaja * This function is used by master to set parent for any clock. 524f9627312SRajan Vaja * 525f9627312SRajan Vaja * Return: Returns status, either success or error+reason 526f9627312SRajan Vaja */ 52770c0d364SRajan Vaja int zynqmp_pm_clock_setparent(u32 clock_id, u32 parent_id) 528f9627312SRajan Vaja { 529f9627312SRajan Vaja return zynqmp_pm_invoke_fn(PM_CLOCK_SETPARENT, clock_id, 530f9627312SRajan Vaja parent_id, 0, 0, NULL); 531f9627312SRajan Vaja } 53270c0d364SRajan Vaja EXPORT_SYMBOL_GPL(zynqmp_pm_clock_setparent); 533f9627312SRajan Vaja 534f9627312SRajan Vaja /** 535f9627312SRajan Vaja * zynqmp_pm_clock_getparent() - Get the clock parent for given id 536f9627312SRajan Vaja * @clock_id: ID of the clock 537f9627312SRajan Vaja * @parent_id: parent id 538f9627312SRajan Vaja * 539f9627312SRajan Vaja * This function is used by master to get parent index 540f9627312SRajan Vaja * for any clock. 541f9627312SRajan Vaja * 542f9627312SRajan Vaja * Return: Returns status, either success or error+reason 543f9627312SRajan Vaja */ 54470c0d364SRajan Vaja int zynqmp_pm_clock_getparent(u32 clock_id, u32 *parent_id) 545f9627312SRajan Vaja { 546f9627312SRajan Vaja u32 ret_payload[PAYLOAD_ARG_CNT]; 547f9627312SRajan Vaja int ret; 548f9627312SRajan Vaja 549f9627312SRajan Vaja ret = zynqmp_pm_invoke_fn(PM_CLOCK_GETPARENT, clock_id, 0, 550f9627312SRajan Vaja 0, 0, ret_payload); 551f9627312SRajan Vaja *parent_id = ret_payload[1]; 552f9627312SRajan Vaja 553f9627312SRajan Vaja return ret; 55459ecdd77SRajan Vaja } 55570c0d364SRajan Vaja EXPORT_SYMBOL_GPL(zynqmp_pm_clock_getparent); 55659ecdd77SRajan Vaja 5573b0296b8SRajan Vaja /** 558426c8d85SRajan Vaja * zynqmp_pm_set_pll_frac_mode() - PM API for set PLL mode 5593b0296b8SRajan Vaja * 560426c8d85SRajan Vaja * @clk_id: PLL clock ID 561426c8d85SRajan Vaja * @mode: PLL mode (PLL_MODE_FRAC/PLL_MODE_INT) 5623b0296b8SRajan Vaja * 563426c8d85SRajan Vaja * This function sets PLL mode 5643b0296b8SRajan Vaja * 5653b0296b8SRajan Vaja * Return: Returns status, either success or error+reason 5663b0296b8SRajan Vaja */ 567426c8d85SRajan Vaja int zynqmp_pm_set_pll_frac_mode(u32 clk_id, u32 mode) 5683b0296b8SRajan Vaja { 569426c8d85SRajan Vaja return zynqmp_pm_invoke_fn(PM_IOCTL, 0, IOCTL_SET_PLL_FRAC_MODE, 570426c8d85SRajan Vaja clk_id, mode, NULL); 5713b0296b8SRajan Vaja } 572426c8d85SRajan Vaja EXPORT_SYMBOL_GPL(zynqmp_pm_set_pll_frac_mode); 573426c8d85SRajan Vaja 574426c8d85SRajan Vaja /** 575426c8d85SRajan Vaja * zynqmp_pm_get_pll_frac_mode() - PM API for get PLL mode 576426c8d85SRajan Vaja * 577426c8d85SRajan Vaja * @clk_id: PLL clock ID 578426c8d85SRajan Vaja * @mode: PLL mode 579426c8d85SRajan Vaja * 580426c8d85SRajan Vaja * This function return current PLL mode 581426c8d85SRajan Vaja * 582426c8d85SRajan Vaja * Return: Returns status, either success or error+reason 583426c8d85SRajan Vaja */ 584426c8d85SRajan Vaja int zynqmp_pm_get_pll_frac_mode(u32 clk_id, u32 *mode) 585426c8d85SRajan Vaja { 586426c8d85SRajan Vaja return zynqmp_pm_invoke_fn(PM_IOCTL, 0, IOCTL_GET_PLL_FRAC_MODE, 587426c8d85SRajan Vaja clk_id, 0, mode); 588426c8d85SRajan Vaja } 589426c8d85SRajan Vaja EXPORT_SYMBOL_GPL(zynqmp_pm_get_pll_frac_mode); 590426c8d85SRajan Vaja 591426c8d85SRajan Vaja /** 592426c8d85SRajan Vaja * zynqmp_pm_set_pll_frac_data() - PM API for setting pll fraction data 593426c8d85SRajan Vaja * 594426c8d85SRajan Vaja * @clk_id: PLL clock ID 595426c8d85SRajan Vaja * @data: fraction data 596426c8d85SRajan Vaja * 597426c8d85SRajan Vaja * This function sets fraction data. 598426c8d85SRajan Vaja * It is valid for fraction mode only. 599426c8d85SRajan Vaja * 600426c8d85SRajan Vaja * Return: Returns status, either success or error+reason 601426c8d85SRajan Vaja */ 602426c8d85SRajan Vaja int zynqmp_pm_set_pll_frac_data(u32 clk_id, u32 data) 603426c8d85SRajan Vaja { 604426c8d85SRajan Vaja return zynqmp_pm_invoke_fn(PM_IOCTL, 0, IOCTL_SET_PLL_FRAC_DATA, 605426c8d85SRajan Vaja clk_id, data, NULL); 606426c8d85SRajan Vaja } 607426c8d85SRajan Vaja EXPORT_SYMBOL_GPL(zynqmp_pm_set_pll_frac_data); 608426c8d85SRajan Vaja 609426c8d85SRajan Vaja /** 610426c8d85SRajan Vaja * zynqmp_pm_get_pll_frac_data() - PM API for getting pll fraction data 611426c8d85SRajan Vaja * 612426c8d85SRajan Vaja * @clk_id: PLL clock ID 613426c8d85SRajan Vaja * @data: fraction data 614426c8d85SRajan Vaja * 615426c8d85SRajan Vaja * This function returns fraction data value. 616426c8d85SRajan Vaja * 617426c8d85SRajan Vaja * Return: Returns status, either success or error+reason 618426c8d85SRajan Vaja */ 619426c8d85SRajan Vaja int zynqmp_pm_get_pll_frac_data(u32 clk_id, u32 *data) 620426c8d85SRajan Vaja { 621426c8d85SRajan Vaja return zynqmp_pm_invoke_fn(PM_IOCTL, 0, IOCTL_GET_PLL_FRAC_DATA, 622426c8d85SRajan Vaja clk_id, 0, data); 623426c8d85SRajan Vaja } 624426c8d85SRajan Vaja EXPORT_SYMBOL_GPL(zynqmp_pm_get_pll_frac_data); 625426c8d85SRajan Vaja 626426c8d85SRajan Vaja /** 627426c8d85SRajan Vaja * zynqmp_pm_set_sd_tapdelay() - Set tap delay for the SD device 628426c8d85SRajan Vaja * 629332bee16SMichal Simek * @node_id: Node ID of the device 630332bee16SMichal Simek * @type: Type of tap delay to set (input/output) 631332bee16SMichal Simek * @value: Value to set fot the tap delay 632426c8d85SRajan Vaja * 633426c8d85SRajan Vaja * This function sets input/output tap delay for the SD device. 634426c8d85SRajan Vaja * 635332bee16SMichal Simek * Return: Returns status, either success or error+reason 636426c8d85SRajan Vaja */ 637426c8d85SRajan Vaja int zynqmp_pm_set_sd_tapdelay(u32 node_id, u32 type, u32 value) 638426c8d85SRajan Vaja { 639426c8d85SRajan Vaja return zynqmp_pm_invoke_fn(PM_IOCTL, node_id, IOCTL_SET_SD_TAPDELAY, 640426c8d85SRajan Vaja type, value, NULL); 641426c8d85SRajan Vaja } 642426c8d85SRajan Vaja EXPORT_SYMBOL_GPL(zynqmp_pm_set_sd_tapdelay); 643426c8d85SRajan Vaja 644426c8d85SRajan Vaja /** 645426c8d85SRajan Vaja * zynqmp_pm_sd_dll_reset() - Reset DLL logic 646426c8d85SRajan Vaja * 647332bee16SMichal Simek * @node_id: Node ID of the device 648332bee16SMichal Simek * @type: Reset type 649426c8d85SRajan Vaja * 650426c8d85SRajan Vaja * This function resets DLL logic for the SD device. 651426c8d85SRajan Vaja * 652332bee16SMichal Simek * Return: Returns status, either success or error+reason 653426c8d85SRajan Vaja */ 654426c8d85SRajan Vaja int zynqmp_pm_sd_dll_reset(u32 node_id, u32 type) 655426c8d85SRajan Vaja { 656f4426311SManish Narani return zynqmp_pm_invoke_fn(PM_IOCTL, node_id, IOCTL_SD_DLL_RESET, 657426c8d85SRajan Vaja type, 0, NULL); 658426c8d85SRajan Vaja } 659426c8d85SRajan Vaja EXPORT_SYMBOL_GPL(zynqmp_pm_sd_dll_reset); 6603b0296b8SRajan Vaja 661bc3843d4SNava kishore Manne /** 66274e78adcSSai Krishna Potthuri * zynqmp_pm_ospi_mux_select() - OSPI Mux selection 66374e78adcSSai Krishna Potthuri * 66474e78adcSSai Krishna Potthuri * @dev_id: Device Id of the OSPI device. 66574e78adcSSai Krishna Potthuri * @select: OSPI Mux select value. 66674e78adcSSai Krishna Potthuri * 66774e78adcSSai Krishna Potthuri * This function select the OSPI Mux. 66874e78adcSSai Krishna Potthuri * 66974e78adcSSai Krishna Potthuri * Return: Returns status, either success or error+reason 67074e78adcSSai Krishna Potthuri */ 67174e78adcSSai Krishna Potthuri int zynqmp_pm_ospi_mux_select(u32 dev_id, u32 select) 67274e78adcSSai Krishna Potthuri { 67374e78adcSSai Krishna Potthuri return zynqmp_pm_invoke_fn(PM_IOCTL, dev_id, IOCTL_OSPI_MUX_SELECT, 67474e78adcSSai Krishna Potthuri select, 0, NULL); 67574e78adcSSai Krishna Potthuri } 67674e78adcSSai Krishna Potthuri EXPORT_SYMBOL_GPL(zynqmp_pm_ospi_mux_select); 67774e78adcSSai Krishna Potthuri 67874e78adcSSai Krishna Potthuri /** 6794f680b72SRajan Vaja * zynqmp_pm_write_ggs() - PM API for writing global general storage (ggs) 680332bee16SMichal Simek * @index: GGS register index 681332bee16SMichal Simek * @value: Register value to be written 6824f680b72SRajan Vaja * 6834f680b72SRajan Vaja * This function writes value to GGS register. 6844f680b72SRajan Vaja * 685332bee16SMichal Simek * Return: Returns status, either success or error+reason 6864f680b72SRajan Vaja */ 6874f680b72SRajan Vaja int zynqmp_pm_write_ggs(u32 index, u32 value) 6884f680b72SRajan Vaja { 6894f680b72SRajan Vaja return zynqmp_pm_invoke_fn(PM_IOCTL, 0, IOCTL_WRITE_GGS, 6904f680b72SRajan Vaja index, value, NULL); 6914f680b72SRajan Vaja } 6924f680b72SRajan Vaja EXPORT_SYMBOL_GPL(zynqmp_pm_write_ggs); 6934f680b72SRajan Vaja 6944f680b72SRajan Vaja /** 6952a8faf8dSMichal Simek * zynqmp_pm_read_ggs() - PM API for reading global general storage (ggs) 696332bee16SMichal Simek * @index: GGS register index 697332bee16SMichal Simek * @value: Register value to be written 6984f680b72SRajan Vaja * 6994f680b72SRajan Vaja * This function returns GGS register value. 7004f680b72SRajan Vaja * 701332bee16SMichal Simek * Return: Returns status, either success or error+reason 7024f680b72SRajan Vaja */ 7034f680b72SRajan Vaja int zynqmp_pm_read_ggs(u32 index, u32 *value) 7044f680b72SRajan Vaja { 7054f680b72SRajan Vaja return zynqmp_pm_invoke_fn(PM_IOCTL, 0, IOCTL_READ_GGS, 7064f680b72SRajan Vaja index, 0, value); 7074f680b72SRajan Vaja } 7084f680b72SRajan Vaja EXPORT_SYMBOL_GPL(zynqmp_pm_read_ggs); 7094f680b72SRajan Vaja 7104f680b72SRajan Vaja /** 7114f680b72SRajan Vaja * zynqmp_pm_write_pggs() - PM API for writing persistent global general 7124f680b72SRajan Vaja * storage (pggs) 713332bee16SMichal Simek * @index: PGGS register index 714332bee16SMichal Simek * @value: Register value to be written 7154f680b72SRajan Vaja * 7164f680b72SRajan Vaja * This function writes value to PGGS register. 7174f680b72SRajan Vaja * 718332bee16SMichal Simek * Return: Returns status, either success or error+reason 7194f680b72SRajan Vaja */ 7204f680b72SRajan Vaja int zynqmp_pm_write_pggs(u32 index, u32 value) 7214f680b72SRajan Vaja { 7224f680b72SRajan Vaja return zynqmp_pm_invoke_fn(PM_IOCTL, 0, IOCTL_WRITE_PGGS, index, value, 7234f680b72SRajan Vaja NULL); 7244f680b72SRajan Vaja } 7254f680b72SRajan Vaja EXPORT_SYMBOL_GPL(zynqmp_pm_write_pggs); 7264f680b72SRajan Vaja 7274f680b72SRajan Vaja /** 7282a8faf8dSMichal Simek * zynqmp_pm_read_pggs() - PM API for reading persistent global general 7294f680b72SRajan Vaja * storage (pggs) 730332bee16SMichal Simek * @index: PGGS register index 731332bee16SMichal Simek * @value: Register value to be written 7324f680b72SRajan Vaja * 7334f680b72SRajan Vaja * This function returns PGGS register value. 7344f680b72SRajan Vaja * 735332bee16SMichal Simek * Return: Returns status, either success or error+reason 7364f680b72SRajan Vaja */ 7374f680b72SRajan Vaja int zynqmp_pm_read_pggs(u32 index, u32 *value) 7384f680b72SRajan Vaja { 7394f680b72SRajan Vaja return zynqmp_pm_invoke_fn(PM_IOCTL, 0, IOCTL_READ_PGGS, index, 0, 7404f680b72SRajan Vaja value); 7414f680b72SRajan Vaja } 7424f680b72SRajan Vaja EXPORT_SYMBOL_GPL(zynqmp_pm_read_pggs); 7434f680b72SRajan Vaja 7444f680b72SRajan Vaja /** 745a2cc220aSRajan Vaja * zynqmp_pm_set_boot_health_status() - PM API for setting healthy boot status 746332bee16SMichal Simek * @value: Status value to be written 747a2cc220aSRajan Vaja * 748a2cc220aSRajan Vaja * This function sets healthy bit value to indicate boot health status 749a2cc220aSRajan Vaja * to firmware. 750a2cc220aSRajan Vaja * 751332bee16SMichal Simek * Return: Returns status, either success or error+reason 752a2cc220aSRajan Vaja */ 753a2cc220aSRajan Vaja int zynqmp_pm_set_boot_health_status(u32 value) 754a2cc220aSRajan Vaja { 755a2cc220aSRajan Vaja return zynqmp_pm_invoke_fn(PM_IOCTL, 0, IOCTL_SET_BOOT_HEALTH_STATUS, 756a2cc220aSRajan Vaja value, 0, NULL); 757a2cc220aSRajan Vaja } 758a2cc220aSRajan Vaja 759a2cc220aSRajan Vaja /** 760bc3843d4SNava kishore Manne * zynqmp_pm_reset_assert - Request setting of reset (1 - assert, 0 - release) 761bc3843d4SNava kishore Manne * @reset: Reset to be configured 762bc3843d4SNava kishore Manne * @assert_flag: Flag stating should reset be asserted (1) or 763bc3843d4SNava kishore Manne * released (0) 764bc3843d4SNava kishore Manne * 765bc3843d4SNava kishore Manne * Return: Returns status, either success or error+reason 766bc3843d4SNava kishore Manne */ 767cf23ec35SRajan Vaja int zynqmp_pm_reset_assert(const enum zynqmp_pm_reset reset, 768bc3843d4SNava kishore Manne const enum zynqmp_pm_reset_action assert_flag) 769bc3843d4SNava kishore Manne { 770bc3843d4SNava kishore Manne return zynqmp_pm_invoke_fn(PM_RESET_ASSERT, reset, assert_flag, 771bc3843d4SNava kishore Manne 0, 0, NULL); 772bc3843d4SNava kishore Manne } 773cf23ec35SRajan Vaja EXPORT_SYMBOL_GPL(zynqmp_pm_reset_assert); 774bc3843d4SNava kishore Manne 775bc3843d4SNava kishore Manne /** 776bc3843d4SNava kishore Manne * zynqmp_pm_reset_get_status - Get status of the reset 777bc3843d4SNava kishore Manne * @reset: Reset whose status should be returned 778bc3843d4SNava kishore Manne * @status: Returned status 779bc3843d4SNava kishore Manne * 780bc3843d4SNava kishore Manne * Return: Returns status, either success or error+reason 781bc3843d4SNava kishore Manne */ 7821b413581SRajan Vaja int zynqmp_pm_reset_get_status(const enum zynqmp_pm_reset reset, u32 *status) 783bc3843d4SNava kishore Manne { 784bc3843d4SNava kishore Manne u32 ret_payload[PAYLOAD_ARG_CNT]; 785bc3843d4SNava kishore Manne int ret; 786bc3843d4SNava kishore Manne 787bc3843d4SNava kishore Manne if (!status) 788bc3843d4SNava kishore Manne return -EINVAL; 789bc3843d4SNava kishore Manne 790bc3843d4SNava kishore Manne ret = zynqmp_pm_invoke_fn(PM_RESET_GET_STATUS, reset, 0, 791bc3843d4SNava kishore Manne 0, 0, ret_payload); 792bc3843d4SNava kishore Manne *status = ret_payload[1]; 793bc3843d4SNava kishore Manne 794bc3843d4SNava kishore Manne return ret; 795bc3843d4SNava kishore Manne } 7961b413581SRajan Vaja EXPORT_SYMBOL_GPL(zynqmp_pm_reset_get_status); 797bc3843d4SNava kishore Manne 798e178df31SJolly Shah /** 799e840deccSNava kishore Manne * zynqmp_pm_fpga_load - Perform the fpga load 800e840deccSNava kishore Manne * @address: Address to write to 801e840deccSNava kishore Manne * @size: pl bitstream size 802e840deccSNava kishore Manne * @flags: Bitstream type 803e840deccSNava kishore Manne * -XILINX_ZYNQMP_PM_FPGA_FULL: FPGA full reconfiguration 804e840deccSNava kishore Manne * -XILINX_ZYNQMP_PM_FPGA_PARTIAL: FPGA partial reconfiguration 805e840deccSNava kishore Manne * 806e840deccSNava kishore Manne * This function provides access to pmufw. To transfer 807e840deccSNava kishore Manne * the required bitstream into PL. 808e840deccSNava kishore Manne * 809e840deccSNava kishore Manne * Return: Returns status, either success or error+reason 810e840deccSNava kishore Manne */ 8114db8180fSRajan Vaja int zynqmp_pm_fpga_load(const u64 address, const u32 size, const u32 flags) 812e840deccSNava kishore Manne { 813e840deccSNava kishore Manne return zynqmp_pm_invoke_fn(PM_FPGA_LOAD, lower_32_bits(address), 814e840deccSNava kishore Manne upper_32_bits(address), size, flags, NULL); 815e840deccSNava kishore Manne } 81656a9a806SNathan Chancellor EXPORT_SYMBOL_GPL(zynqmp_pm_fpga_load); 817e840deccSNava kishore Manne 818e840deccSNava kishore Manne /** 819e840deccSNava kishore Manne * zynqmp_pm_fpga_get_status - Read value from PCAP status register 820e840deccSNava kishore Manne * @value: Value to read 821e840deccSNava kishore Manne * 822e840deccSNava kishore Manne * This function provides access to the pmufw to get the PCAP 823e840deccSNava kishore Manne * status 824e840deccSNava kishore Manne * 825e840deccSNava kishore Manne * Return: Returns status, either success or error+reason 826e840deccSNava kishore Manne */ 8274db8180fSRajan Vaja int zynqmp_pm_fpga_get_status(u32 *value) 828e840deccSNava kishore Manne { 829e840deccSNava kishore Manne u32 ret_payload[PAYLOAD_ARG_CNT]; 830e840deccSNava kishore Manne int ret; 831e840deccSNava kishore Manne 832e840deccSNava kishore Manne if (!value) 833e840deccSNava kishore Manne return -EINVAL; 834e840deccSNava kishore Manne 835e840deccSNava kishore Manne ret = zynqmp_pm_invoke_fn(PM_FPGA_GET_STATUS, 0, 0, 0, 0, ret_payload); 836e840deccSNava kishore Manne *value = ret_payload[1]; 837e840deccSNava kishore Manne 838e840deccSNava kishore Manne return ret; 839e840deccSNava kishore Manne } 84056a9a806SNathan Chancellor EXPORT_SYMBOL_GPL(zynqmp_pm_fpga_get_status); 841e840deccSNava kishore Manne 842e840deccSNava kishore Manne /** 843fa989ae7SSai Krishna Potthuri * zynqmp_pm_pinctrl_request - Request Pin from firmware 844fa989ae7SSai Krishna Potthuri * @pin: Pin number to request 845fa989ae7SSai Krishna Potthuri * 846fa989ae7SSai Krishna Potthuri * This function requests pin from firmware. 847fa989ae7SSai Krishna Potthuri * 848fa989ae7SSai Krishna Potthuri * Return: Returns status, either success or error+reason. 849fa989ae7SSai Krishna Potthuri */ 850fa989ae7SSai Krishna Potthuri int zynqmp_pm_pinctrl_request(const u32 pin) 851fa989ae7SSai Krishna Potthuri { 852fa989ae7SSai Krishna Potthuri return zynqmp_pm_invoke_fn(PM_PINCTRL_REQUEST, pin, 0, 0, 0, NULL); 853fa989ae7SSai Krishna Potthuri } 854fa989ae7SSai Krishna Potthuri EXPORT_SYMBOL_GPL(zynqmp_pm_pinctrl_request); 855fa989ae7SSai Krishna Potthuri 856fa989ae7SSai Krishna Potthuri /** 857fa989ae7SSai Krishna Potthuri * zynqmp_pm_pinctrl_release - Inform firmware that Pin control is released 858fa989ae7SSai Krishna Potthuri * @pin: Pin number to release 859fa989ae7SSai Krishna Potthuri * 860fa989ae7SSai Krishna Potthuri * This function release pin from firmware. 861fa989ae7SSai Krishna Potthuri * 862fa989ae7SSai Krishna Potthuri * Return: Returns status, either success or error+reason. 863fa989ae7SSai Krishna Potthuri */ 864fa989ae7SSai Krishna Potthuri int zynqmp_pm_pinctrl_release(const u32 pin) 865fa989ae7SSai Krishna Potthuri { 866fa989ae7SSai Krishna Potthuri return zynqmp_pm_invoke_fn(PM_PINCTRL_RELEASE, pin, 0, 0, 0, NULL); 867fa989ae7SSai Krishna Potthuri } 868fa989ae7SSai Krishna Potthuri EXPORT_SYMBOL_GPL(zynqmp_pm_pinctrl_release); 869fa989ae7SSai Krishna Potthuri 870fa989ae7SSai Krishna Potthuri /** 871fa989ae7SSai Krishna Potthuri * zynqmp_pm_pinctrl_get_function - Read function id set for the given pin 872fa989ae7SSai Krishna Potthuri * @pin: Pin number 873fa989ae7SSai Krishna Potthuri * @id: Buffer to store function ID 874fa989ae7SSai Krishna Potthuri * 875fa989ae7SSai Krishna Potthuri * This function provides the function currently set for the given pin. 876fa989ae7SSai Krishna Potthuri * 877fa989ae7SSai Krishna Potthuri * Return: Returns status, either success or error+reason 878fa989ae7SSai Krishna Potthuri */ 879fa989ae7SSai Krishna Potthuri int zynqmp_pm_pinctrl_get_function(const u32 pin, u32 *id) 880fa989ae7SSai Krishna Potthuri { 881fa989ae7SSai Krishna Potthuri u32 ret_payload[PAYLOAD_ARG_CNT]; 882fa989ae7SSai Krishna Potthuri int ret; 883fa989ae7SSai Krishna Potthuri 884fa989ae7SSai Krishna Potthuri if (!id) 885fa989ae7SSai Krishna Potthuri return -EINVAL; 886fa989ae7SSai Krishna Potthuri 887fa989ae7SSai Krishna Potthuri ret = zynqmp_pm_invoke_fn(PM_PINCTRL_GET_FUNCTION, pin, 0, 888fa989ae7SSai Krishna Potthuri 0, 0, ret_payload); 889fa989ae7SSai Krishna Potthuri *id = ret_payload[1]; 890fa989ae7SSai Krishna Potthuri 891fa989ae7SSai Krishna Potthuri return ret; 892fa989ae7SSai Krishna Potthuri } 893fa989ae7SSai Krishna Potthuri EXPORT_SYMBOL_GPL(zynqmp_pm_pinctrl_get_function); 894fa989ae7SSai Krishna Potthuri 895fa989ae7SSai Krishna Potthuri /** 896fa989ae7SSai Krishna Potthuri * zynqmp_pm_pinctrl_set_function - Set requested function for the pin 897fa989ae7SSai Krishna Potthuri * @pin: Pin number 898fa989ae7SSai Krishna Potthuri * @id: Function ID to set 899fa989ae7SSai Krishna Potthuri * 900fa989ae7SSai Krishna Potthuri * This function sets requested function for the given pin. 901fa989ae7SSai Krishna Potthuri * 902fa989ae7SSai Krishna Potthuri * Return: Returns status, either success or error+reason. 903fa989ae7SSai Krishna Potthuri */ 904fa989ae7SSai Krishna Potthuri int zynqmp_pm_pinctrl_set_function(const u32 pin, const u32 id) 905fa989ae7SSai Krishna Potthuri { 906fa989ae7SSai Krishna Potthuri return zynqmp_pm_invoke_fn(PM_PINCTRL_SET_FUNCTION, pin, id, 907fa989ae7SSai Krishna Potthuri 0, 0, NULL); 908fa989ae7SSai Krishna Potthuri } 909fa989ae7SSai Krishna Potthuri EXPORT_SYMBOL_GPL(zynqmp_pm_pinctrl_set_function); 910fa989ae7SSai Krishna Potthuri 911fa989ae7SSai Krishna Potthuri /** 912fa989ae7SSai Krishna Potthuri * zynqmp_pm_pinctrl_get_config - Get configuration parameter for the pin 913fa989ae7SSai Krishna Potthuri * @pin: Pin number 914fa989ae7SSai Krishna Potthuri * @param: Parameter to get 915fa989ae7SSai Krishna Potthuri * @value: Buffer to store parameter value 916fa989ae7SSai Krishna Potthuri * 917fa989ae7SSai Krishna Potthuri * This function gets requested configuration parameter for the given pin. 918fa989ae7SSai Krishna Potthuri * 919fa989ae7SSai Krishna Potthuri * Return: Returns status, either success or error+reason. 920fa989ae7SSai Krishna Potthuri */ 921fa989ae7SSai Krishna Potthuri int zynqmp_pm_pinctrl_get_config(const u32 pin, const u32 param, 922fa989ae7SSai Krishna Potthuri u32 *value) 923fa989ae7SSai Krishna Potthuri { 924fa989ae7SSai Krishna Potthuri u32 ret_payload[PAYLOAD_ARG_CNT]; 925fa989ae7SSai Krishna Potthuri int ret; 926fa989ae7SSai Krishna Potthuri 927fa989ae7SSai Krishna Potthuri if (!value) 928fa989ae7SSai Krishna Potthuri return -EINVAL; 929fa989ae7SSai Krishna Potthuri 930fa989ae7SSai Krishna Potthuri ret = zynqmp_pm_invoke_fn(PM_PINCTRL_CONFIG_PARAM_GET, pin, param, 931fa989ae7SSai Krishna Potthuri 0, 0, ret_payload); 932fa989ae7SSai Krishna Potthuri *value = ret_payload[1]; 933fa989ae7SSai Krishna Potthuri 934fa989ae7SSai Krishna Potthuri return ret; 935fa989ae7SSai Krishna Potthuri } 936fa989ae7SSai Krishna Potthuri EXPORT_SYMBOL_GPL(zynqmp_pm_pinctrl_get_config); 937fa989ae7SSai Krishna Potthuri 938fa989ae7SSai Krishna Potthuri /** 939fa989ae7SSai Krishna Potthuri * zynqmp_pm_pinctrl_set_config - Set configuration parameter for the pin 940fa989ae7SSai Krishna Potthuri * @pin: Pin number 941fa989ae7SSai Krishna Potthuri * @param: Parameter to set 942fa989ae7SSai Krishna Potthuri * @value: Parameter value to set 943fa989ae7SSai Krishna Potthuri * 944fa989ae7SSai Krishna Potthuri * This function sets requested configuration parameter for the given pin. 945fa989ae7SSai Krishna Potthuri * 946fa989ae7SSai Krishna Potthuri * Return: Returns status, either success or error+reason. 947fa989ae7SSai Krishna Potthuri */ 948fa989ae7SSai Krishna Potthuri int zynqmp_pm_pinctrl_set_config(const u32 pin, const u32 param, 949fa989ae7SSai Krishna Potthuri u32 value) 950fa989ae7SSai Krishna Potthuri { 951fa989ae7SSai Krishna Potthuri return zynqmp_pm_invoke_fn(PM_PINCTRL_CONFIG_PARAM_SET, pin, 952fa989ae7SSai Krishna Potthuri param, value, 0, NULL); 953fa989ae7SSai Krishna Potthuri } 954fa989ae7SSai Krishna Potthuri EXPORT_SYMBOL_GPL(zynqmp_pm_pinctrl_set_config); 955fa989ae7SSai Krishna Potthuri 956fa989ae7SSai Krishna Potthuri /** 95723c64d76SPiyush Mehta * zynqmp_pm_bootmode_read() - PM Config API for read bootpin status 95823c64d76SPiyush Mehta * @ps_mode: Returned output value of ps_mode 95923c64d76SPiyush Mehta * 96023c64d76SPiyush Mehta * This API function is to be used for notify the power management controller 96123c64d76SPiyush Mehta * to read bootpin status. 96223c64d76SPiyush Mehta * 96323c64d76SPiyush Mehta * Return: status, either success or error+reason 96423c64d76SPiyush Mehta */ 96523c64d76SPiyush Mehta unsigned int zynqmp_pm_bootmode_read(u32 *ps_mode) 96623c64d76SPiyush Mehta { 96723c64d76SPiyush Mehta unsigned int ret; 96823c64d76SPiyush Mehta u32 ret_payload[PAYLOAD_ARG_CNT]; 96923c64d76SPiyush Mehta 97023c64d76SPiyush Mehta ret = zynqmp_pm_invoke_fn(PM_MMIO_READ, CRL_APB_BOOT_PIN_CTRL, 0, 97123c64d76SPiyush Mehta 0, 0, ret_payload); 97223c64d76SPiyush Mehta 97323c64d76SPiyush Mehta *ps_mode = ret_payload[1]; 97423c64d76SPiyush Mehta 97523c64d76SPiyush Mehta return ret; 97623c64d76SPiyush Mehta } 97723c64d76SPiyush Mehta EXPORT_SYMBOL_GPL(zynqmp_pm_bootmode_read); 97823c64d76SPiyush Mehta 97923c64d76SPiyush Mehta /** 98023c64d76SPiyush Mehta * zynqmp_pm_bootmode_write() - PM Config API for Configure bootpin 98123c64d76SPiyush Mehta * @ps_mode: Value to be written to the bootpin ctrl register 98223c64d76SPiyush Mehta * 98323c64d76SPiyush Mehta * This API function is to be used for notify the power management controller 98423c64d76SPiyush Mehta * to configure bootpin. 98523c64d76SPiyush Mehta * 98623c64d76SPiyush Mehta * Return: Returns status, either success or error+reason 98723c64d76SPiyush Mehta */ 98823c64d76SPiyush Mehta int zynqmp_pm_bootmode_write(u32 ps_mode) 98923c64d76SPiyush Mehta { 99023c64d76SPiyush Mehta return zynqmp_pm_invoke_fn(PM_MMIO_WRITE, CRL_APB_BOOT_PIN_CTRL, 99123c64d76SPiyush Mehta CRL_APB_BOOTPIN_CTRL_MASK, ps_mode, 0, NULL); 99223c64d76SPiyush Mehta } 99323c64d76SPiyush Mehta EXPORT_SYMBOL_GPL(zynqmp_pm_bootmode_write); 99423c64d76SPiyush Mehta 99523c64d76SPiyush Mehta /** 996e178df31SJolly Shah * zynqmp_pm_init_finalize() - PM call to inform firmware that the caller 997e178df31SJolly Shah * master has initialized its own power management 998e178df31SJolly Shah * 999332bee16SMichal Simek * Return: Returns status, either success or error+reason 1000332bee16SMichal Simek * 1001e178df31SJolly Shah * This API function is to be used for notify the power management controller 1002e178df31SJolly Shah * about the completed power management initialization. 1003e178df31SJolly Shah */ 10049474da95SRajan Vaja int zynqmp_pm_init_finalize(void) 1005e178df31SJolly Shah { 1006e178df31SJolly Shah return zynqmp_pm_invoke_fn(PM_PM_INIT_FINALIZE, 0, 0, 0, 0, NULL); 1007e178df31SJolly Shah } 10089474da95SRajan Vaja EXPORT_SYMBOL_GPL(zynqmp_pm_init_finalize); 1009e178df31SJolly Shah 1010e178df31SJolly Shah /** 1011e178df31SJolly Shah * zynqmp_pm_set_suspend_mode() - Set system suspend mode 1012e178df31SJolly Shah * @mode: Mode to set for system suspend 1013e178df31SJolly Shah * 1014e178df31SJolly Shah * This API function is used to set mode of system suspend. 1015e178df31SJolly Shah * 1016e178df31SJolly Shah * Return: Returns status, either success or error+reason 1017e178df31SJolly Shah */ 1018951d0a97SRajan Vaja int zynqmp_pm_set_suspend_mode(u32 mode) 1019e178df31SJolly Shah { 1020e178df31SJolly Shah return zynqmp_pm_invoke_fn(PM_SET_SUSPEND_MODE, mode, 0, 0, 0, NULL); 1021e178df31SJolly Shah } 1022951d0a97SRajan Vaja EXPORT_SYMBOL_GPL(zynqmp_pm_set_suspend_mode); 1023e178df31SJolly Shah 1024c1986ac3SRajan Vaja /** 1025c1986ac3SRajan Vaja * zynqmp_pm_request_node() - Request a node with specific capabilities 1026c1986ac3SRajan Vaja * @node: Node ID of the slave 1027c1986ac3SRajan Vaja * @capabilities: Requested capabilities of the slave 1028c1986ac3SRajan Vaja * @qos: Quality of service (not supported) 1029c1986ac3SRajan Vaja * @ack: Flag to specify whether acknowledge is requested 1030c1986ac3SRajan Vaja * 1031c1986ac3SRajan Vaja * This function is used by master to request particular node from firmware. 1032c1986ac3SRajan Vaja * Every master must request node before using it. 1033c1986ac3SRajan Vaja * 1034c1986ac3SRajan Vaja * Return: Returns status, either success or error+reason 1035c1986ac3SRajan Vaja */ 1036bf8b27edSRajan Vaja int zynqmp_pm_request_node(const u32 node, const u32 capabilities, 1037bf8b27edSRajan Vaja const u32 qos, const enum zynqmp_pm_request_ack ack) 1038c1986ac3SRajan Vaja { 1039c1986ac3SRajan Vaja return zynqmp_pm_invoke_fn(PM_REQUEST_NODE, node, capabilities, 1040c1986ac3SRajan Vaja qos, ack, NULL); 1041c1986ac3SRajan Vaja } 1042bf8b27edSRajan Vaja EXPORT_SYMBOL_GPL(zynqmp_pm_request_node); 1043c1986ac3SRajan Vaja 1044c1986ac3SRajan Vaja /** 1045c1986ac3SRajan Vaja * zynqmp_pm_release_node() - Release a node 1046c1986ac3SRajan Vaja * @node: Node ID of the slave 1047c1986ac3SRajan Vaja * 1048c1986ac3SRajan Vaja * This function is used by master to inform firmware that master 1049c1986ac3SRajan Vaja * has released node. Once released, master must not use that node 1050c1986ac3SRajan Vaja * without re-request. 1051c1986ac3SRajan Vaja * 1052c1986ac3SRajan Vaja * Return: Returns status, either success or error+reason 1053c1986ac3SRajan Vaja */ 105407fb1a46SRajan Vaja int zynqmp_pm_release_node(const u32 node) 1055c1986ac3SRajan Vaja { 1056c1986ac3SRajan Vaja return zynqmp_pm_invoke_fn(PM_RELEASE_NODE, node, 0, 0, 0, NULL); 1057c1986ac3SRajan Vaja } 105807fb1a46SRajan Vaja EXPORT_SYMBOL_GPL(zynqmp_pm_release_node); 1059c1986ac3SRajan Vaja 1060c1986ac3SRajan Vaja /** 1061c1986ac3SRajan Vaja * zynqmp_pm_set_requirement() - PM call to set requirement for PM slaves 1062c1986ac3SRajan Vaja * @node: Node ID of the slave 1063c1986ac3SRajan Vaja * @capabilities: Requested capabilities of the slave 1064c1986ac3SRajan Vaja * @qos: Quality of service (not supported) 1065c1986ac3SRajan Vaja * @ack: Flag to specify whether acknowledge is requested 1066c1986ac3SRajan Vaja * 1067c1986ac3SRajan Vaja * This API function is to be used for slaves a PU already has requested 1068c1986ac3SRajan Vaja * to change its capabilities. 1069c1986ac3SRajan Vaja * 1070c1986ac3SRajan Vaja * Return: Returns status, either success or error+reason 1071c1986ac3SRajan Vaja */ 1072cbbbda71SRajan Vaja int zynqmp_pm_set_requirement(const u32 node, const u32 capabilities, 1073c1986ac3SRajan Vaja const u32 qos, 1074c1986ac3SRajan Vaja const enum zynqmp_pm_request_ack ack) 1075c1986ac3SRajan Vaja { 1076c1986ac3SRajan Vaja return zynqmp_pm_invoke_fn(PM_SET_REQUIREMENT, node, capabilities, 1077c1986ac3SRajan Vaja qos, ack, NULL); 1078c1986ac3SRajan Vaja } 1079cbbbda71SRajan Vaja EXPORT_SYMBOL_GPL(zynqmp_pm_set_requirement); 1080c1986ac3SRajan Vaja 1081057a0fb6SKalyani Akula /** 10822b9fc773SNava kishore Manne * zynqmp_pm_load_pdi - Load and process PDI 10832b9fc773SNava kishore Manne * @src: Source device where PDI is located 10842b9fc773SNava kishore Manne * @address: PDI src address 10852b9fc773SNava kishore Manne * 10862b9fc773SNava kishore Manne * This function provides support to load PDI from linux 10872b9fc773SNava kishore Manne * 10882b9fc773SNava kishore Manne * Return: Returns status, either success or error+reason 10892b9fc773SNava kishore Manne */ 10902b9fc773SNava kishore Manne int zynqmp_pm_load_pdi(const u32 src, const u64 address) 10912b9fc773SNava kishore Manne { 10922b9fc773SNava kishore Manne return zynqmp_pm_invoke_fn(PM_LOAD_PDI, src, 10932b9fc773SNava kishore Manne lower_32_bits(address), 10942b9fc773SNava kishore Manne upper_32_bits(address), 0, NULL); 10952b9fc773SNava kishore Manne } 10962b9fc773SNava kishore Manne EXPORT_SYMBOL_GPL(zynqmp_pm_load_pdi); 10972b9fc773SNava kishore Manne 10982b9fc773SNava kishore Manne /** 10992a8faf8dSMichal Simek * zynqmp_pm_aes_engine - Access AES hardware to encrypt/decrypt the data using 1100057a0fb6SKalyani Akula * AES-GCM core. 1101057a0fb6SKalyani Akula * @address: Address of the AesParams structure. 1102057a0fb6SKalyani Akula * @out: Returned output value 1103057a0fb6SKalyani Akula * 1104057a0fb6SKalyani Akula * Return: Returns status, either success or error code. 1105057a0fb6SKalyani Akula */ 1106bc86f9c5SRajan Vaja int zynqmp_pm_aes_engine(const u64 address, u32 *out) 1107057a0fb6SKalyani Akula { 1108057a0fb6SKalyani Akula u32 ret_payload[PAYLOAD_ARG_CNT]; 1109057a0fb6SKalyani Akula int ret; 1110057a0fb6SKalyani Akula 1111057a0fb6SKalyani Akula if (!out) 1112057a0fb6SKalyani Akula return -EINVAL; 1113057a0fb6SKalyani Akula 1114057a0fb6SKalyani Akula ret = zynqmp_pm_invoke_fn(PM_SECURE_AES, upper_32_bits(address), 1115057a0fb6SKalyani Akula lower_32_bits(address), 1116057a0fb6SKalyani Akula 0, 0, ret_payload); 1117057a0fb6SKalyani Akula *out = ret_payload[1]; 1118057a0fb6SKalyani Akula 1119057a0fb6SKalyani Akula return ret; 1120057a0fb6SKalyani Akula } 1121bc86f9c5SRajan Vaja EXPORT_SYMBOL_GPL(zynqmp_pm_aes_engine); 1122057a0fb6SKalyani Akula 1123fdd2ed88SRajan Vaja /** 1124*80f940efSHarsha * zynqmp_pm_sha_hash - Access the SHA engine to calculate the hash 1125*80f940efSHarsha * @address: Address of the data/ Address of output buffer where 1126*80f940efSHarsha * hash should be stored. 1127*80f940efSHarsha * @size: Size of the data. 1128*80f940efSHarsha * @flags: 1129*80f940efSHarsha * BIT(0) - for initializing csudma driver and SHA3(Here address 1130*80f940efSHarsha * and size inputs can be NULL). 1131*80f940efSHarsha * BIT(1) - to call Sha3_Update API which can be called multiple 1132*80f940efSHarsha * times when data is not contiguous. 1133*80f940efSHarsha * BIT(2) - to get final hash of the whole updated data. 1134*80f940efSHarsha * Hash will be overwritten at provided address with 1135*80f940efSHarsha * 48 bytes. 1136*80f940efSHarsha * 1137*80f940efSHarsha * Return: Returns status, either success or error code. 1138*80f940efSHarsha */ 1139*80f940efSHarsha int zynqmp_pm_sha_hash(const u64 address, const u32 size, const u32 flags) 1140*80f940efSHarsha { 1141*80f940efSHarsha u32 lower_addr = lower_32_bits(address); 1142*80f940efSHarsha u32 upper_addr = upper_32_bits(address); 1143*80f940efSHarsha 1144*80f940efSHarsha return zynqmp_pm_invoke_fn(PM_SECURE_SHA, upper_addr, lower_addr, 1145*80f940efSHarsha size, flags, NULL); 1146*80f940efSHarsha } 1147*80f940efSHarsha EXPORT_SYMBOL_GPL(zynqmp_pm_sha_hash); 1148*80f940efSHarsha 1149*80f940efSHarsha /** 11501881eadbSAbhyuday Godhasara * zynqmp_pm_register_notifier() - PM API for register a subsystem 11511881eadbSAbhyuday Godhasara * to be notified about specific 11521881eadbSAbhyuday Godhasara * event/error. 11531881eadbSAbhyuday Godhasara * @node: Node ID to which the event is related. 11541881eadbSAbhyuday Godhasara * @event: Event Mask of Error events for which wants to get notified. 11551881eadbSAbhyuday Godhasara * @wake: Wake subsystem upon capturing the event if value 1 11561881eadbSAbhyuday Godhasara * @enable: Enable the registration for value 1, disable for value 0 11571881eadbSAbhyuday Godhasara * 11581881eadbSAbhyuday Godhasara * This function is used to register/un-register for particular node-event 11591881eadbSAbhyuday Godhasara * combination in firmware. 11601881eadbSAbhyuday Godhasara * 11611881eadbSAbhyuday Godhasara * Return: Returns status, either success or error+reason 11621881eadbSAbhyuday Godhasara */ 11631881eadbSAbhyuday Godhasara 11641881eadbSAbhyuday Godhasara int zynqmp_pm_register_notifier(const u32 node, const u32 event, 11651881eadbSAbhyuday Godhasara const u32 wake, const u32 enable) 11661881eadbSAbhyuday Godhasara { 11671881eadbSAbhyuday Godhasara return zynqmp_pm_invoke_fn(PM_REGISTER_NOTIFIER, node, event, 11681881eadbSAbhyuday Godhasara wake, enable, NULL); 11691881eadbSAbhyuday Godhasara } 11701881eadbSAbhyuday Godhasara EXPORT_SYMBOL_GPL(zynqmp_pm_register_notifier); 11711881eadbSAbhyuday Godhasara 11721881eadbSAbhyuday Godhasara /** 1173fdd2ed88SRajan Vaja * zynqmp_pm_system_shutdown - PM call to request a system shutdown or restart 1174fdd2ed88SRajan Vaja * @type: Shutdown or restart? 0 for shutdown, 1 for restart 1175fdd2ed88SRajan Vaja * @subtype: Specifies which system should be restarted or shut down 1176fdd2ed88SRajan Vaja * 1177fdd2ed88SRajan Vaja * Return: Returns status, either success or error+reason 1178fdd2ed88SRajan Vaja */ 1179fdd2ed88SRajan Vaja int zynqmp_pm_system_shutdown(const u32 type, const u32 subtype) 1180fdd2ed88SRajan Vaja { 1181fdd2ed88SRajan Vaja return zynqmp_pm_invoke_fn(PM_SYSTEM_SHUTDOWN, type, subtype, 1182fdd2ed88SRajan Vaja 0, 0, NULL); 1183fdd2ed88SRajan Vaja } 1184fdd2ed88SRajan Vaja 1185b3ae24c4SRajan Vaja /** 1186b3ae24c4SRajan Vaja * struct zynqmp_pm_shutdown_scope - Struct for shutdown scope 1187b3ae24c4SRajan Vaja * @subtype: Shutdown subtype 1188b3ae24c4SRajan Vaja * @name: Matching string for scope argument 1189b3ae24c4SRajan Vaja * 1190b3ae24c4SRajan Vaja * This struct encapsulates mapping between shutdown scope ID and string. 1191b3ae24c4SRajan Vaja */ 1192b3ae24c4SRajan Vaja struct zynqmp_pm_shutdown_scope { 1193b3ae24c4SRajan Vaja const enum zynqmp_pm_shutdown_subtype subtype; 1194b3ae24c4SRajan Vaja const char *name; 1195b3ae24c4SRajan Vaja }; 1196b3ae24c4SRajan Vaja 1197b3ae24c4SRajan Vaja static struct zynqmp_pm_shutdown_scope shutdown_scopes[] = { 1198b3ae24c4SRajan Vaja [ZYNQMP_PM_SHUTDOWN_SUBTYPE_SUBSYSTEM] = { 1199b3ae24c4SRajan Vaja .subtype = ZYNQMP_PM_SHUTDOWN_SUBTYPE_SUBSYSTEM, 1200b3ae24c4SRajan Vaja .name = "subsystem", 1201b3ae24c4SRajan Vaja }, 1202b3ae24c4SRajan Vaja [ZYNQMP_PM_SHUTDOWN_SUBTYPE_PS_ONLY] = { 1203b3ae24c4SRajan Vaja .subtype = ZYNQMP_PM_SHUTDOWN_SUBTYPE_PS_ONLY, 1204b3ae24c4SRajan Vaja .name = "ps_only", 1205b3ae24c4SRajan Vaja }, 1206b3ae24c4SRajan Vaja [ZYNQMP_PM_SHUTDOWN_SUBTYPE_SYSTEM] = { 1207b3ae24c4SRajan Vaja .subtype = ZYNQMP_PM_SHUTDOWN_SUBTYPE_SYSTEM, 1208b3ae24c4SRajan Vaja .name = "system", 1209b3ae24c4SRajan Vaja }, 1210b3ae24c4SRajan Vaja }; 1211b3ae24c4SRajan Vaja 1212b3ae24c4SRajan Vaja static struct zynqmp_pm_shutdown_scope *selected_scope = 1213b3ae24c4SRajan Vaja &shutdown_scopes[ZYNQMP_PM_SHUTDOWN_SUBTYPE_SYSTEM]; 1214b3ae24c4SRajan Vaja 1215b3ae24c4SRajan Vaja /** 1216b3ae24c4SRajan Vaja * zynqmp_pm_is_shutdown_scope_valid - Check if shutdown scope string is valid 1217b3ae24c4SRajan Vaja * @scope_string: Shutdown scope string 1218b3ae24c4SRajan Vaja * 1219b3ae24c4SRajan Vaja * Return: Return pointer to matching shutdown scope struct from 1220b3ae24c4SRajan Vaja * array of available options in system if string is valid, 1221b3ae24c4SRajan Vaja * otherwise returns NULL. 1222b3ae24c4SRajan Vaja */ 1223b3ae24c4SRajan Vaja static struct zynqmp_pm_shutdown_scope* 1224b3ae24c4SRajan Vaja zynqmp_pm_is_shutdown_scope_valid(const char *scope_string) 1225b3ae24c4SRajan Vaja { 1226b3ae24c4SRajan Vaja int count; 1227b3ae24c4SRajan Vaja 1228b3ae24c4SRajan Vaja for (count = 0; count < ARRAY_SIZE(shutdown_scopes); count++) 1229b3ae24c4SRajan Vaja if (sysfs_streq(scope_string, shutdown_scopes[count].name)) 1230b3ae24c4SRajan Vaja return &shutdown_scopes[count]; 1231b3ae24c4SRajan Vaja 1232b3ae24c4SRajan Vaja return NULL; 1233b3ae24c4SRajan Vaja } 1234b3ae24c4SRajan Vaja 1235b3ae24c4SRajan Vaja static ssize_t shutdown_scope_show(struct device *device, 1236b3ae24c4SRajan Vaja struct device_attribute *attr, 1237b3ae24c4SRajan Vaja char *buf) 1238b3ae24c4SRajan Vaja { 1239b3ae24c4SRajan Vaja int i; 1240b3ae24c4SRajan Vaja 1241b3ae24c4SRajan Vaja for (i = 0; i < ARRAY_SIZE(shutdown_scopes); i++) { 1242b3ae24c4SRajan Vaja if (&shutdown_scopes[i] == selected_scope) { 1243b3ae24c4SRajan Vaja strcat(buf, "["); 1244b3ae24c4SRajan Vaja strcat(buf, shutdown_scopes[i].name); 1245b3ae24c4SRajan Vaja strcat(buf, "]"); 1246b3ae24c4SRajan Vaja } else { 1247b3ae24c4SRajan Vaja strcat(buf, shutdown_scopes[i].name); 1248b3ae24c4SRajan Vaja } 1249b3ae24c4SRajan Vaja strcat(buf, " "); 1250b3ae24c4SRajan Vaja } 1251b3ae24c4SRajan Vaja strcat(buf, "\n"); 1252b3ae24c4SRajan Vaja 1253b3ae24c4SRajan Vaja return strlen(buf); 1254b3ae24c4SRajan Vaja } 1255b3ae24c4SRajan Vaja 1256b3ae24c4SRajan Vaja static ssize_t shutdown_scope_store(struct device *device, 1257b3ae24c4SRajan Vaja struct device_attribute *attr, 1258b3ae24c4SRajan Vaja const char *buf, size_t count) 1259b3ae24c4SRajan Vaja { 1260b3ae24c4SRajan Vaja int ret; 1261b3ae24c4SRajan Vaja struct zynqmp_pm_shutdown_scope *scope; 1262b3ae24c4SRajan Vaja 1263b3ae24c4SRajan Vaja scope = zynqmp_pm_is_shutdown_scope_valid(buf); 1264b3ae24c4SRajan Vaja if (!scope) 1265b3ae24c4SRajan Vaja return -EINVAL; 1266b3ae24c4SRajan Vaja 1267b3ae24c4SRajan Vaja ret = zynqmp_pm_system_shutdown(ZYNQMP_PM_SHUTDOWN_TYPE_SETSCOPE_ONLY, 1268b3ae24c4SRajan Vaja scope->subtype); 1269b3ae24c4SRajan Vaja if (ret) { 1270b3ae24c4SRajan Vaja pr_err("unable to set shutdown scope %s\n", buf); 1271b3ae24c4SRajan Vaja return ret; 1272b3ae24c4SRajan Vaja } 1273b3ae24c4SRajan Vaja 1274b3ae24c4SRajan Vaja selected_scope = scope; 1275b3ae24c4SRajan Vaja 1276b3ae24c4SRajan Vaja return count; 1277b3ae24c4SRajan Vaja } 1278b3ae24c4SRajan Vaja 1279b3ae24c4SRajan Vaja static DEVICE_ATTR_RW(shutdown_scope); 1280b3ae24c4SRajan Vaja 1281a2cc220aSRajan Vaja static ssize_t health_status_store(struct device *device, 1282a2cc220aSRajan Vaja struct device_attribute *attr, 1283a2cc220aSRajan Vaja const char *buf, size_t count) 1284a2cc220aSRajan Vaja { 1285a2cc220aSRajan Vaja int ret; 1286a2cc220aSRajan Vaja unsigned int value; 1287a2cc220aSRajan Vaja 1288a2cc220aSRajan Vaja ret = kstrtouint(buf, 10, &value); 1289a2cc220aSRajan Vaja if (ret) 1290a2cc220aSRajan Vaja return ret; 1291a2cc220aSRajan Vaja 1292a2cc220aSRajan Vaja ret = zynqmp_pm_set_boot_health_status(value); 1293a2cc220aSRajan Vaja if (ret) { 1294a2cc220aSRajan Vaja dev_err(device, "unable to set healthy bit value to %u\n", 1295a2cc220aSRajan Vaja value); 1296a2cc220aSRajan Vaja return ret; 1297a2cc220aSRajan Vaja } 1298a2cc220aSRajan Vaja 1299a2cc220aSRajan Vaja return count; 1300a2cc220aSRajan Vaja } 1301a2cc220aSRajan Vaja 1302a2cc220aSRajan Vaja static DEVICE_ATTR_WO(health_status); 1303a2cc220aSRajan Vaja 1304ae5c961dSRajan Vaja static ssize_t ggs_show(struct device *device, 1305ae5c961dSRajan Vaja struct device_attribute *attr, 1306ae5c961dSRajan Vaja char *buf, 1307ae5c961dSRajan Vaja u32 reg) 1308ae5c961dSRajan Vaja { 1309ae5c961dSRajan Vaja int ret; 1310ae5c961dSRajan Vaja u32 ret_payload[PAYLOAD_ARG_CNT]; 1311ae5c961dSRajan Vaja 1312ae5c961dSRajan Vaja ret = zynqmp_pm_read_ggs(reg, ret_payload); 1313ae5c961dSRajan Vaja if (ret) 1314ae5c961dSRajan Vaja return ret; 1315ae5c961dSRajan Vaja 1316ae5c961dSRajan Vaja return sprintf(buf, "0x%x\n", ret_payload[1]); 1317ae5c961dSRajan Vaja } 1318ae5c961dSRajan Vaja 1319ae5c961dSRajan Vaja static ssize_t ggs_store(struct device *device, 1320ae5c961dSRajan Vaja struct device_attribute *attr, 1321ae5c961dSRajan Vaja const char *buf, size_t count, 1322ae5c961dSRajan Vaja u32 reg) 1323ae5c961dSRajan Vaja { 1324ae5c961dSRajan Vaja long value; 1325ae5c961dSRajan Vaja int ret; 1326ae5c961dSRajan Vaja 1327ae5c961dSRajan Vaja if (reg >= GSS_NUM_REGS) 1328ae5c961dSRajan Vaja return -EINVAL; 1329ae5c961dSRajan Vaja 1330ae5c961dSRajan Vaja ret = kstrtol(buf, 16, &value); 1331ae5c961dSRajan Vaja if (ret) { 1332ae5c961dSRajan Vaja count = -EFAULT; 1333ae5c961dSRajan Vaja goto err; 1334ae5c961dSRajan Vaja } 1335ae5c961dSRajan Vaja 1336ae5c961dSRajan Vaja ret = zynqmp_pm_write_ggs(reg, value); 1337ae5c961dSRajan Vaja if (ret) 1338ae5c961dSRajan Vaja count = -EFAULT; 1339ae5c961dSRajan Vaja err: 1340ae5c961dSRajan Vaja return count; 1341ae5c961dSRajan Vaja } 1342ae5c961dSRajan Vaja 1343ae5c961dSRajan Vaja /* GGS register show functions */ 1344ae5c961dSRajan Vaja #define GGS0_SHOW(N) \ 1345ae5c961dSRajan Vaja ssize_t ggs##N##_show(struct device *device, \ 1346ae5c961dSRajan Vaja struct device_attribute *attr, \ 1347ae5c961dSRajan Vaja char *buf) \ 1348ae5c961dSRajan Vaja { \ 1349ae5c961dSRajan Vaja return ggs_show(device, attr, buf, N); \ 1350ae5c961dSRajan Vaja } 1351ae5c961dSRajan Vaja 1352ae5c961dSRajan Vaja static GGS0_SHOW(0); 1353ae5c961dSRajan Vaja static GGS0_SHOW(1); 1354ae5c961dSRajan Vaja static GGS0_SHOW(2); 1355ae5c961dSRajan Vaja static GGS0_SHOW(3); 1356ae5c961dSRajan Vaja 1357ae5c961dSRajan Vaja /* GGS register store function */ 1358ae5c961dSRajan Vaja #define GGS0_STORE(N) \ 1359ae5c961dSRajan Vaja ssize_t ggs##N##_store(struct device *device, \ 1360ae5c961dSRajan Vaja struct device_attribute *attr, \ 1361ae5c961dSRajan Vaja const char *buf, \ 1362ae5c961dSRajan Vaja size_t count) \ 1363ae5c961dSRajan Vaja { \ 1364ae5c961dSRajan Vaja return ggs_store(device, attr, buf, count, N); \ 1365ae5c961dSRajan Vaja } 1366ae5c961dSRajan Vaja 1367ae5c961dSRajan Vaja static GGS0_STORE(0); 1368ae5c961dSRajan Vaja static GGS0_STORE(1); 1369ae5c961dSRajan Vaja static GGS0_STORE(2); 1370ae5c961dSRajan Vaja static GGS0_STORE(3); 1371ae5c961dSRajan Vaja 1372ae5c961dSRajan Vaja static ssize_t pggs_show(struct device *device, 1373ae5c961dSRajan Vaja struct device_attribute *attr, 1374ae5c961dSRajan Vaja char *buf, 1375ae5c961dSRajan Vaja u32 reg) 1376ae5c961dSRajan Vaja { 1377ae5c961dSRajan Vaja int ret; 1378ae5c961dSRajan Vaja u32 ret_payload[PAYLOAD_ARG_CNT]; 1379ae5c961dSRajan Vaja 1380ae5c961dSRajan Vaja ret = zynqmp_pm_read_pggs(reg, ret_payload); 1381ae5c961dSRajan Vaja if (ret) 1382ae5c961dSRajan Vaja return ret; 1383ae5c961dSRajan Vaja 1384ae5c961dSRajan Vaja return sprintf(buf, "0x%x\n", ret_payload[1]); 1385ae5c961dSRajan Vaja } 1386ae5c961dSRajan Vaja 1387ae5c961dSRajan Vaja static ssize_t pggs_store(struct device *device, 1388ae5c961dSRajan Vaja struct device_attribute *attr, 1389ae5c961dSRajan Vaja const char *buf, size_t count, 1390ae5c961dSRajan Vaja u32 reg) 1391ae5c961dSRajan Vaja { 1392ae5c961dSRajan Vaja long value; 1393ae5c961dSRajan Vaja int ret; 1394ae5c961dSRajan Vaja 1395ae5c961dSRajan Vaja if (reg >= GSS_NUM_REGS) 1396ae5c961dSRajan Vaja return -EINVAL; 1397ae5c961dSRajan Vaja 1398ae5c961dSRajan Vaja ret = kstrtol(buf, 16, &value); 1399ae5c961dSRajan Vaja if (ret) { 1400ae5c961dSRajan Vaja count = -EFAULT; 1401ae5c961dSRajan Vaja goto err; 1402ae5c961dSRajan Vaja } 1403ae5c961dSRajan Vaja 1404ae5c961dSRajan Vaja ret = zynqmp_pm_write_pggs(reg, value); 1405ae5c961dSRajan Vaja if (ret) 1406ae5c961dSRajan Vaja count = -EFAULT; 1407ae5c961dSRajan Vaja 1408ae5c961dSRajan Vaja err: 1409ae5c961dSRajan Vaja return count; 1410ae5c961dSRajan Vaja } 1411ae5c961dSRajan Vaja 1412ae5c961dSRajan Vaja #define PGGS0_SHOW(N) \ 1413ae5c961dSRajan Vaja ssize_t pggs##N##_show(struct device *device, \ 1414ae5c961dSRajan Vaja struct device_attribute *attr, \ 1415ae5c961dSRajan Vaja char *buf) \ 1416ae5c961dSRajan Vaja { \ 1417ae5c961dSRajan Vaja return pggs_show(device, attr, buf, N); \ 1418ae5c961dSRajan Vaja } 1419ae5c961dSRajan Vaja 1420ae5c961dSRajan Vaja #define PGGS0_STORE(N) \ 1421ae5c961dSRajan Vaja ssize_t pggs##N##_store(struct device *device, \ 1422ae5c961dSRajan Vaja struct device_attribute *attr, \ 1423ae5c961dSRajan Vaja const char *buf, \ 1424ae5c961dSRajan Vaja size_t count) \ 1425ae5c961dSRajan Vaja { \ 1426ae5c961dSRajan Vaja return pggs_store(device, attr, buf, count, N); \ 1427ae5c961dSRajan Vaja } 1428ae5c961dSRajan Vaja 1429ae5c961dSRajan Vaja /* PGGS register show functions */ 1430ae5c961dSRajan Vaja static PGGS0_SHOW(0); 1431ae5c961dSRajan Vaja static PGGS0_SHOW(1); 1432ae5c961dSRajan Vaja static PGGS0_SHOW(2); 1433ae5c961dSRajan Vaja static PGGS0_SHOW(3); 1434ae5c961dSRajan Vaja 1435ae5c961dSRajan Vaja /* PGGS register store functions */ 1436ae5c961dSRajan Vaja static PGGS0_STORE(0); 1437ae5c961dSRajan Vaja static PGGS0_STORE(1); 1438ae5c961dSRajan Vaja static PGGS0_STORE(2); 1439ae5c961dSRajan Vaja static PGGS0_STORE(3); 1440ae5c961dSRajan Vaja 1441ae5c961dSRajan Vaja /* GGS register attributes */ 1442ae5c961dSRajan Vaja static DEVICE_ATTR_RW(ggs0); 1443ae5c961dSRajan Vaja static DEVICE_ATTR_RW(ggs1); 1444ae5c961dSRajan Vaja static DEVICE_ATTR_RW(ggs2); 1445ae5c961dSRajan Vaja static DEVICE_ATTR_RW(ggs3); 1446ae5c961dSRajan Vaja 1447ae5c961dSRajan Vaja /* PGGS register attributes */ 1448ae5c961dSRajan Vaja static DEVICE_ATTR_RW(pggs0); 1449ae5c961dSRajan Vaja static DEVICE_ATTR_RW(pggs1); 1450ae5c961dSRajan Vaja static DEVICE_ATTR_RW(pggs2); 1451ae5c961dSRajan Vaja static DEVICE_ATTR_RW(pggs3); 1452ae5c961dSRajan Vaja 1453ae5c961dSRajan Vaja static struct attribute *zynqmp_firmware_attrs[] = { 1454ae5c961dSRajan Vaja &dev_attr_ggs0.attr, 1455ae5c961dSRajan Vaja &dev_attr_ggs1.attr, 1456ae5c961dSRajan Vaja &dev_attr_ggs2.attr, 1457ae5c961dSRajan Vaja &dev_attr_ggs3.attr, 1458ae5c961dSRajan Vaja &dev_attr_pggs0.attr, 1459ae5c961dSRajan Vaja &dev_attr_pggs1.attr, 1460ae5c961dSRajan Vaja &dev_attr_pggs2.attr, 1461ae5c961dSRajan Vaja &dev_attr_pggs3.attr, 1462b3ae24c4SRajan Vaja &dev_attr_shutdown_scope.attr, 1463a2cc220aSRajan Vaja &dev_attr_health_status.attr, 1464ae5c961dSRajan Vaja NULL, 1465ae5c961dSRajan Vaja }; 1466ae5c961dSRajan Vaja 1467ae5c961dSRajan Vaja ATTRIBUTE_GROUPS(zynqmp_firmware); 1468ae5c961dSRajan Vaja 146976582671SRajan Vaja static int zynqmp_firmware_probe(struct platform_device *pdev) 147076582671SRajan Vaja { 147176582671SRajan Vaja struct device *dev = &pdev->dev; 147276582671SRajan Vaja struct device_node *np; 147376582671SRajan Vaja int ret; 147476582671SRajan Vaja 147576582671SRajan Vaja np = of_find_compatible_node(NULL, NULL, "xlnx,zynqmp"); 1476af3f1afaSJolly Shah if (!np) { 1477af3f1afaSJolly Shah np = of_find_compatible_node(NULL, NULL, "xlnx,versal"); 147876582671SRajan Vaja if (!np) 147976582671SRajan Vaja return 0; 1480461011b1SRavi Patel 1481461011b1SRavi Patel feature_check_enabled = true; 1482af3f1afaSJolly Shah } 148376582671SRajan Vaja of_node_put(np); 148476582671SRajan Vaja 148576582671SRajan Vaja ret = get_set_conduit_method(dev->of_node); 148676582671SRajan Vaja if (ret) 148776582671SRajan Vaja return ret; 148876582671SRajan Vaja 148976582671SRajan Vaja /* Check PM API version number */ 1490168e05c1SRajan Vaja ret = zynqmp_pm_get_api_version(&pm_api_version); 1491168e05c1SRajan Vaja if (ret) 1492168e05c1SRajan Vaja return ret; 1493168e05c1SRajan Vaja 149476582671SRajan Vaja if (pm_api_version < ZYNQMP_PM_VERSION) { 149576582671SRajan Vaja panic("%s Platform Management API version error. Expected: v%d.%d - Found: v%d.%d\n", 149676582671SRajan Vaja __func__, 149776582671SRajan Vaja ZYNQMP_PM_VERSION_MAJOR, ZYNQMP_PM_VERSION_MINOR, 149876582671SRajan Vaja pm_api_version >> 16, pm_api_version & 0xFFFF); 149976582671SRajan Vaja } 150076582671SRajan Vaja 150176582671SRajan Vaja pr_info("%s Platform Management API v%d.%d\n", __func__, 150276582671SRajan Vaja pm_api_version >> 16, pm_api_version & 0xFFFF); 150376582671SRajan Vaja 150476582671SRajan Vaja /* Check trustzone version number */ 150576582671SRajan Vaja ret = zynqmp_pm_get_trustzone_version(&pm_tz_version); 150676582671SRajan Vaja if (ret) 150776582671SRajan Vaja panic("Legacy trustzone found without version support\n"); 150876582671SRajan Vaja 150976582671SRajan Vaja if (pm_tz_version < ZYNQMP_TZ_VERSION) 151076582671SRajan Vaja panic("%s Trustzone version error. Expected: v%d.%d - Found: v%d.%d\n", 151176582671SRajan Vaja __func__, 151276582671SRajan Vaja ZYNQMP_TZ_VERSION_MAJOR, ZYNQMP_TZ_VERSION_MINOR, 151376582671SRajan Vaja pm_tz_version >> 16, pm_tz_version & 0xFFFF); 151476582671SRajan Vaja 151576582671SRajan Vaja pr_info("%s Trustzone version v%d.%d\n", __func__, 151676582671SRajan Vaja pm_tz_version >> 16, pm_tz_version & 0xFFFF); 151776582671SRajan Vaja 1518e23d9c6dSJolly Shah ret = mfd_add_devices(&pdev->dev, PLATFORM_DEVID_NONE, firmware_devs, 1519e23d9c6dSJolly Shah ARRAY_SIZE(firmware_devs), NULL, 0, NULL); 1520e23d9c6dSJolly Shah if (ret) { 1521e23d9c6dSJolly Shah dev_err(&pdev->dev, "failed to add MFD devices %d\n", ret); 1522e23d9c6dSJolly Shah return ret; 1523e23d9c6dSJolly Shah } 1524e23d9c6dSJolly Shah 152565f0539bSChristophe JAILLET zynqmp_pm_api_debugfs_init(); 152665f0539bSChristophe JAILLET 1527a515814eSAbhyuday Godhasara np = of_find_compatible_node(NULL, NULL, "xlnx,versal"); 1528a515814eSAbhyuday Godhasara if (np) { 1529a515814eSAbhyuday Godhasara em_dev = platform_device_register_data(&pdev->dev, "xlnx_event_manager", 1530a515814eSAbhyuday Godhasara -1, NULL, 0); 1531a515814eSAbhyuday Godhasara if (IS_ERR(em_dev)) 1532a515814eSAbhyuday Godhasara dev_err_probe(&pdev->dev, PTR_ERR(em_dev), "EM register fail with error\n"); 1533a515814eSAbhyuday Godhasara } 1534a515814eSAbhyuday Godhasara of_node_put(np); 1535a515814eSAbhyuday Godhasara 153676582671SRajan Vaja return of_platform_populate(dev->of_node, NULL, NULL, dev); 153776582671SRajan Vaja } 153876582671SRajan Vaja 153976582671SRajan Vaja static int zynqmp_firmware_remove(struct platform_device *pdev) 154076582671SRajan Vaja { 1541acfdd185SAmit Sunil Dhamne struct pm_api_feature_data *feature_data; 1542f1f21becSTejas Patel struct hlist_node *tmp; 1543acfdd185SAmit Sunil Dhamne int i; 1544acfdd185SAmit Sunil Dhamne 1545e23d9c6dSJolly Shah mfd_remove_devices(&pdev->dev); 1546b3217252SRajan Vaja zynqmp_pm_api_debugfs_exit(); 1547b3217252SRajan Vaja 1548f1f21becSTejas Patel hash_for_each_safe(pm_api_features_map, i, tmp, feature_data, hentry) { 1549acfdd185SAmit Sunil Dhamne hash_del(&feature_data->hentry); 1550acfdd185SAmit Sunil Dhamne kfree(feature_data); 1551acfdd185SAmit Sunil Dhamne } 1552acfdd185SAmit Sunil Dhamne 1553a515814eSAbhyuday Godhasara platform_device_unregister(em_dev); 1554a515814eSAbhyuday Godhasara 155576582671SRajan Vaja return 0; 155676582671SRajan Vaja } 155776582671SRajan Vaja 155876582671SRajan Vaja static const struct of_device_id zynqmp_firmware_of_match[] = { 155976582671SRajan Vaja {.compatible = "xlnx,zynqmp-firmware"}, 1560af3f1afaSJolly Shah {.compatible = "xlnx,versal-firmware"}, 156176582671SRajan Vaja {}, 156276582671SRajan Vaja }; 156376582671SRajan Vaja MODULE_DEVICE_TABLE(of, zynqmp_firmware_of_match); 156476582671SRajan Vaja 156576582671SRajan Vaja static struct platform_driver zynqmp_firmware_driver = { 156676582671SRajan Vaja .driver = { 156776582671SRajan Vaja .name = "zynqmp_firmware", 156876582671SRajan Vaja .of_match_table = zynqmp_firmware_of_match, 1569ae5c961dSRajan Vaja .dev_groups = zynqmp_firmware_groups, 157076582671SRajan Vaja }, 157176582671SRajan Vaja .probe = zynqmp_firmware_probe, 157276582671SRajan Vaja .remove = zynqmp_firmware_remove, 157376582671SRajan Vaja }; 157476582671SRajan Vaja module_platform_driver(zynqmp_firmware_driver); 1575