zynqmp.c 52 KB

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