zynqmp.c 58 KB

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