1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Xilinx Zynq MPSoC Firmware layer 4 * 5 * Copyright (C) 2014-2018 Xilinx, Inc. 6 * 7 * Michal Simek <michal.simek@xilinx.com> 8 * Davorin Mista <davorin.mista@aggios.com> 9 * Jolly Shah <jollys@xilinx.com> 10 * Rajan Vaja <rajanv@xilinx.com> 11 */ 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/slab.h> 22 #include <linux/uaccess.h> 23 24 #include <linux/firmware/xlnx-zynqmp.h> 25 #include "zynqmp-debug.h" 26 27 static const struct zynqmp_eemi_ops *eemi_ops_tbl; 28 29 static bool feature_check_enabled; 30 static u32 zynqmp_pm_features[PM_API_MAX]; 31 32 static const struct mfd_cell firmware_devs[] = { 33 { 34 .name = "zynqmp_power_controller", 35 }, 36 }; 37 38 /** 39 * zynqmp_pm_ret_code() - Convert PMU-FW error codes to Linux error codes 40 * @ret_status: PMUFW return code 41 * 42 * Return: corresponding Linux error code 43 */ 44 static int zynqmp_pm_ret_code(u32 ret_status) 45 { 46 switch (ret_status) { 47 case XST_PM_SUCCESS: 48 case XST_PM_DOUBLE_REQ: 49 return 0; 50 case XST_PM_NO_FEATURE: 51 return -ENOTSUPP; 52 case XST_PM_NO_ACCESS: 53 return -EACCES; 54 case XST_PM_ABORT_SUSPEND: 55 return -ECANCELED; 56 case XST_PM_MULT_USER: 57 return -EUSERS; 58 case XST_PM_INTERNAL: 59 case XST_PM_CONFLICT: 60 case XST_PM_INVALID_NODE: 61 default: 62 return -EINVAL; 63 } 64 } 65 66 static noinline int do_fw_call_fail(u64 arg0, u64 arg1, u64 arg2, 67 u32 *ret_payload) 68 { 69 return -ENODEV; 70 } 71 72 /* 73 * PM function call wrapper 74 * Invoke do_fw_call_smc or do_fw_call_hvc, depending on the configuration 75 */ 76 static int (*do_fw_call)(u64, u64, u64, u32 *ret_payload) = do_fw_call_fail; 77 78 /** 79 * do_fw_call_smc() - Call system-level platform management layer (SMC) 80 * @arg0: Argument 0 to SMC call 81 * @arg1: Argument 1 to SMC call 82 * @arg2: Argument 2 to SMC call 83 * @ret_payload: Returned value array 84 * 85 * Invoke platform management function via SMC call (no hypervisor present). 86 * 87 * Return: Returns status, either success or error+reason 88 */ 89 static noinline int do_fw_call_smc(u64 arg0, u64 arg1, u64 arg2, 90 u32 *ret_payload) 91 { 92 struct arm_smccc_res res; 93 94 arm_smccc_smc(arg0, arg1, arg2, 0, 0, 0, 0, 0, &res); 95 96 if (ret_payload) { 97 ret_payload[0] = lower_32_bits(res.a0); 98 ret_payload[1] = upper_32_bits(res.a0); 99 ret_payload[2] = lower_32_bits(res.a1); 100 ret_payload[3] = upper_32_bits(res.a1); 101 } 102 103 return zynqmp_pm_ret_code((enum pm_ret_status)res.a0); 104 } 105 106 /** 107 * do_fw_call_hvc() - Call system-level platform management layer (HVC) 108 * @arg0: Argument 0 to HVC call 109 * @arg1: Argument 1 to HVC call 110 * @arg2: Argument 2 to HVC call 111 * @ret_payload: Returned value array 112 * 113 * Invoke platform management function via HVC 114 * HVC-based for communication through hypervisor 115 * (no direct communication with ATF). 116 * 117 * Return: Returns status, either success or error+reason 118 */ 119 static noinline int do_fw_call_hvc(u64 arg0, u64 arg1, u64 arg2, 120 u32 *ret_payload) 121 { 122 struct arm_smccc_res res; 123 124 arm_smccc_hvc(arg0, arg1, arg2, 0, 0, 0, 0, 0, &res); 125 126 if (ret_payload) { 127 ret_payload[0] = lower_32_bits(res.a0); 128 ret_payload[1] = upper_32_bits(res.a0); 129 ret_payload[2] = lower_32_bits(res.a1); 130 ret_payload[3] = upper_32_bits(res.a1); 131 } 132 133 return zynqmp_pm_ret_code((enum pm_ret_status)res.a0); 134 } 135 136 /** 137 * zynqmp_pm_feature() - Check weather given feature is supported or not 138 * @api_id: API ID to check 139 * 140 * Return: Returns status, either success or error+reason 141 */ 142 static int zynqmp_pm_feature(u32 api_id) 143 { 144 int ret; 145 u32 ret_payload[PAYLOAD_ARG_CNT]; 146 u64 smc_arg[2]; 147 148 if (!feature_check_enabled) 149 return 0; 150 151 /* Return value if feature is already checked */ 152 if (zynqmp_pm_features[api_id] != PM_FEATURE_UNCHECKED) 153 return zynqmp_pm_features[api_id]; 154 155 smc_arg[0] = PM_SIP_SVC | PM_FEATURE_CHECK; 156 smc_arg[1] = api_id; 157 158 ret = do_fw_call(smc_arg[0], smc_arg[1], 0, ret_payload); 159 if (ret) { 160 zynqmp_pm_features[api_id] = PM_FEATURE_INVALID; 161 return PM_FEATURE_INVALID; 162 } 163 164 zynqmp_pm_features[api_id] = ret_payload[1]; 165 166 return zynqmp_pm_features[api_id]; 167 } 168 169 /** 170 * zynqmp_pm_invoke_fn() - Invoke the system-level platform management layer 171 * caller function depending on the configuration 172 * @pm_api_id: Requested PM-API call 173 * @arg0: Argument 0 to requested PM-API call 174 * @arg1: Argument 1 to requested PM-API call 175 * @arg2: Argument 2 to requested PM-API call 176 * @arg3: Argument 3 to requested PM-API call 177 * @ret_payload: Returned value array 178 * 179 * Invoke platform management function for SMC or HVC call, depending on 180 * configuration. 181 * Following SMC Calling Convention (SMCCC) for SMC64: 182 * Pm Function Identifier, 183 * PM_SIP_SVC + PM_API_ID = 184 * ((SMC_TYPE_FAST << FUNCID_TYPE_SHIFT) 185 * ((SMC_64) << FUNCID_CC_SHIFT) 186 * ((SIP_START) << FUNCID_OEN_SHIFT) 187 * ((PM_API_ID) & FUNCID_NUM_MASK)) 188 * 189 * PM_SIP_SVC - Registered ZynqMP SIP Service Call. 190 * PM_API_ID - Platform Management API ID. 191 * 192 * Return: Returns status, either success or error+reason 193 */ 194 int zynqmp_pm_invoke_fn(u32 pm_api_id, u32 arg0, u32 arg1, 195 u32 arg2, u32 arg3, u32 *ret_payload) 196 { 197 /* 198 * Added SIP service call Function Identifier 199 * Make sure to stay in x0 register 200 */ 201 u64 smc_arg[4]; 202 203 if (zynqmp_pm_feature(pm_api_id) == PM_FEATURE_INVALID) 204 return -ENOTSUPP; 205 206 smc_arg[0] = PM_SIP_SVC | pm_api_id; 207 smc_arg[1] = ((u64)arg1 << 32) | arg0; 208 smc_arg[2] = ((u64)arg3 << 32) | arg2; 209 210 return do_fw_call(smc_arg[0], smc_arg[1], smc_arg[2], ret_payload); 211 } 212 213 static u32 pm_api_version; 214 static u32 pm_tz_version; 215 216 /** 217 * zynqmp_pm_get_api_version() - Get version number of PMU PM firmware 218 * @version: Returned version value 219 * 220 * Return: Returns status, either success or error+reason 221 */ 222 static int zynqmp_pm_get_api_version(u32 *version) 223 { 224 u32 ret_payload[PAYLOAD_ARG_CNT]; 225 int ret; 226 227 if (!version) 228 return -EINVAL; 229 230 /* Check is PM API version already verified */ 231 if (pm_api_version > 0) { 232 *version = pm_api_version; 233 return 0; 234 } 235 ret = zynqmp_pm_invoke_fn(PM_GET_API_VERSION, 0, 0, 0, 0, ret_payload); 236 *version = ret_payload[1]; 237 238 return ret; 239 } 240 241 /** 242 * zynqmp_pm_get_chipid - Get silicon ID registers 243 * @idcode: IDCODE register 244 * @version: version register 245 * 246 * Return: Returns the status of the operation and the idcode and version 247 * registers in @idcode and @version. 248 */ 249 static int zynqmp_pm_get_chipid(u32 *idcode, u32 *version) 250 { 251 u32 ret_payload[PAYLOAD_ARG_CNT]; 252 int ret; 253 254 if (!idcode || !version) 255 return -EINVAL; 256 257 ret = zynqmp_pm_invoke_fn(PM_GET_CHIPID, 0, 0, 0, 0, ret_payload); 258 *idcode = ret_payload[1]; 259 *version = ret_payload[2]; 260 261 return ret; 262 } 263 264 /** 265 * zynqmp_pm_get_trustzone_version() - Get secure trustzone firmware version 266 * @version: Returned version value 267 * 268 * Return: Returns status, either success or error+reason 269 */ 270 static int zynqmp_pm_get_trustzone_version(u32 *version) 271 { 272 u32 ret_payload[PAYLOAD_ARG_CNT]; 273 int ret; 274 275 if (!version) 276 return -EINVAL; 277 278 /* Check is PM trustzone version already verified */ 279 if (pm_tz_version > 0) { 280 *version = pm_tz_version; 281 return 0; 282 } 283 ret = zynqmp_pm_invoke_fn(PM_GET_TRUSTZONE_VERSION, 0, 0, 284 0, 0, ret_payload); 285 *version = ret_payload[1]; 286 287 return ret; 288 } 289 290 /** 291 * get_set_conduit_method() - Choose SMC or HVC based communication 292 * @np: Pointer to the device_node structure 293 * 294 * Use SMC or HVC-based functions to communicate with EL2/EL3. 295 * 296 * Return: Returns 0 on success or error code 297 */ 298 static int get_set_conduit_method(struct device_node *np) 299 { 300 const char *method; 301 302 if (of_property_read_string(np, "method", &method)) { 303 pr_warn("%s missing \"method\" property\n", __func__); 304 return -ENXIO; 305 } 306 307 if (!strcmp("hvc", method)) { 308 do_fw_call = do_fw_call_hvc; 309 } else if (!strcmp("smc", method)) { 310 do_fw_call = do_fw_call_smc; 311 } else { 312 pr_warn("%s Invalid \"method\" property: %s\n", 313 __func__, method); 314 return -EINVAL; 315 } 316 317 return 0; 318 } 319 320 /** 321 * zynqmp_pm_query_data() - Get query data from firmware 322 * @qdata: Variable to the zynqmp_pm_query_data structure 323 * @out: Returned output value 324 * 325 * Return: Returns status, either success or error+reason 326 */ 327 static int zynqmp_pm_query_data(struct zynqmp_pm_query_data qdata, u32 *out) 328 { 329 int ret; 330 331 ret = zynqmp_pm_invoke_fn(PM_QUERY_DATA, qdata.qid, qdata.arg1, 332 qdata.arg2, qdata.arg3, out); 333 334 /* 335 * For clock name query, all bytes in SMC response are clock name 336 * characters and return code is always success. For invalid clocks, 337 * clock name bytes would be zeros. 338 */ 339 return qdata.qid == PM_QID_CLOCK_GET_NAME ? 0 : ret; 340 } 341 342 /** 343 * zynqmp_pm_clock_enable() - Enable the clock for given id 344 * @clock_id: ID of the clock to be enabled 345 * 346 * This function is used by master to enable the clock 347 * including peripherals and PLL clocks. 348 * 349 * Return: Returns status, either success or error+reason 350 */ 351 static int zynqmp_pm_clock_enable(u32 clock_id) 352 { 353 return zynqmp_pm_invoke_fn(PM_CLOCK_ENABLE, clock_id, 0, 0, 0, NULL); 354 } 355 356 /** 357 * zynqmp_pm_clock_disable() - Disable the clock for given id 358 * @clock_id: ID of the clock to be disable 359 * 360 * This function is used by master to disable the clock 361 * including peripherals and PLL clocks. 362 * 363 * Return: Returns status, either success or error+reason 364 */ 365 static int zynqmp_pm_clock_disable(u32 clock_id) 366 { 367 return zynqmp_pm_invoke_fn(PM_CLOCK_DISABLE, clock_id, 0, 0, 0, NULL); 368 } 369 370 /** 371 * zynqmp_pm_clock_getstate() - Get the clock state for given id 372 * @clock_id: ID of the clock to be queried 373 * @state: 1/0 (Enabled/Disabled) 374 * 375 * This function is used by master to get the state of clock 376 * including peripherals and PLL clocks. 377 * 378 * Return: Returns status, either success or error+reason 379 */ 380 static int zynqmp_pm_clock_getstate(u32 clock_id, u32 *state) 381 { 382 u32 ret_payload[PAYLOAD_ARG_CNT]; 383 int ret; 384 385 ret = zynqmp_pm_invoke_fn(PM_CLOCK_GETSTATE, clock_id, 0, 386 0, 0, ret_payload); 387 *state = ret_payload[1]; 388 389 return ret; 390 } 391 392 /** 393 * zynqmp_pm_clock_setdivider() - Set the clock divider for given id 394 * @clock_id: ID of the clock 395 * @divider: divider value 396 * 397 * This function is used by master to set divider for any clock 398 * to achieve desired rate. 399 * 400 * Return: Returns status, either success or error+reason 401 */ 402 static int zynqmp_pm_clock_setdivider(u32 clock_id, u32 divider) 403 { 404 return zynqmp_pm_invoke_fn(PM_CLOCK_SETDIVIDER, clock_id, divider, 405 0, 0, NULL); 406 } 407 408 /** 409 * zynqmp_pm_clock_getdivider() - Get the clock divider for given id 410 * @clock_id: ID of the clock 411 * @divider: divider value 412 * 413 * This function is used by master to get divider values 414 * for any clock. 415 * 416 * Return: Returns status, either success or error+reason 417 */ 418 static int zynqmp_pm_clock_getdivider(u32 clock_id, u32 *divider) 419 { 420 u32 ret_payload[PAYLOAD_ARG_CNT]; 421 int ret; 422 423 ret = zynqmp_pm_invoke_fn(PM_CLOCK_GETDIVIDER, clock_id, 0, 424 0, 0, ret_payload); 425 *divider = ret_payload[1]; 426 427 return ret; 428 } 429 430 /** 431 * zynqmp_pm_clock_setrate() - Set the clock rate for given id 432 * @clock_id: ID of the clock 433 * @rate: rate value in hz 434 * 435 * This function is used by master to set rate for any clock. 436 * 437 * Return: Returns status, either success or error+reason 438 */ 439 static int zynqmp_pm_clock_setrate(u32 clock_id, u64 rate) 440 { 441 return zynqmp_pm_invoke_fn(PM_CLOCK_SETRATE, clock_id, 442 lower_32_bits(rate), 443 upper_32_bits(rate), 444 0, NULL); 445 } 446 447 /** 448 * zynqmp_pm_clock_getrate() - Get the clock rate for given id 449 * @clock_id: ID of the clock 450 * @rate: rate value in hz 451 * 452 * This function is used by master to get rate 453 * for any clock. 454 * 455 * Return: Returns status, either success or error+reason 456 */ 457 static int zynqmp_pm_clock_getrate(u32 clock_id, u64 *rate) 458 { 459 u32 ret_payload[PAYLOAD_ARG_CNT]; 460 int ret; 461 462 ret = zynqmp_pm_invoke_fn(PM_CLOCK_GETRATE, clock_id, 0, 463 0, 0, ret_payload); 464 *rate = ((u64)ret_payload[2] << 32) | ret_payload[1]; 465 466 return ret; 467 } 468 469 /** 470 * zynqmp_pm_clock_setparent() - Set the clock parent for given id 471 * @clock_id: ID of the clock 472 * @parent_id: parent id 473 * 474 * This function is used by master to set parent for any clock. 475 * 476 * Return: Returns status, either success or error+reason 477 */ 478 static int zynqmp_pm_clock_setparent(u32 clock_id, u32 parent_id) 479 { 480 return zynqmp_pm_invoke_fn(PM_CLOCK_SETPARENT, clock_id, 481 parent_id, 0, 0, NULL); 482 } 483 484 /** 485 * zynqmp_pm_clock_getparent() - Get the clock parent for given id 486 * @clock_id: ID of the clock 487 * @parent_id: parent id 488 * 489 * This function is used by master to get parent index 490 * for any clock. 491 * 492 * Return: Returns status, either success or error+reason 493 */ 494 static int zynqmp_pm_clock_getparent(u32 clock_id, u32 *parent_id) 495 { 496 u32 ret_payload[PAYLOAD_ARG_CNT]; 497 int ret; 498 499 ret = zynqmp_pm_invoke_fn(PM_CLOCK_GETPARENT, clock_id, 0, 500 0, 0, ret_payload); 501 *parent_id = ret_payload[1]; 502 503 return ret; 504 } 505 506 /** 507 * zynqmp_is_valid_ioctl() - Check whether IOCTL ID is valid or not 508 * @ioctl_id: IOCTL ID 509 * 510 * Return: 1 if IOCTL is valid else 0 511 */ 512 static inline int zynqmp_is_valid_ioctl(u32 ioctl_id) 513 { 514 switch (ioctl_id) { 515 case IOCTL_SD_DLL_RESET: 516 case IOCTL_SET_SD_TAPDELAY: 517 case IOCTL_SET_PLL_FRAC_MODE: 518 case IOCTL_GET_PLL_FRAC_MODE: 519 case IOCTL_SET_PLL_FRAC_DATA: 520 case IOCTL_GET_PLL_FRAC_DATA: 521 return 1; 522 default: 523 return 0; 524 } 525 } 526 527 /** 528 * zynqmp_pm_ioctl() - PM IOCTL API for device control and configs 529 * @node_id: Node ID of the device 530 * @ioctl_id: ID of the requested IOCTL 531 * @arg1: Argument 1 to requested IOCTL call 532 * @arg2: Argument 2 to requested IOCTL call 533 * @out: Returned output value 534 * 535 * This function calls IOCTL to firmware for device control and configuration. 536 * 537 * Return: Returns status, either success or error+reason 538 */ 539 static int zynqmp_pm_ioctl(u32 node_id, u32 ioctl_id, u32 arg1, u32 arg2, 540 u32 *out) 541 { 542 if (!zynqmp_is_valid_ioctl(ioctl_id)) 543 return -EINVAL; 544 545 return zynqmp_pm_invoke_fn(PM_IOCTL, node_id, ioctl_id, 546 arg1, arg2, out); 547 } 548 549 /** 550 * zynqmp_pm_reset_assert - Request setting of reset (1 - assert, 0 - release) 551 * @reset: Reset to be configured 552 * @assert_flag: Flag stating should reset be asserted (1) or 553 * released (0) 554 * 555 * Return: Returns status, either success or error+reason 556 */ 557 static int zynqmp_pm_reset_assert(const enum zynqmp_pm_reset reset, 558 const enum zynqmp_pm_reset_action assert_flag) 559 { 560 return zynqmp_pm_invoke_fn(PM_RESET_ASSERT, reset, assert_flag, 561 0, 0, NULL); 562 } 563 564 /** 565 * zynqmp_pm_reset_get_status - Get status of the reset 566 * @reset: Reset whose status should be returned 567 * @status: Returned status 568 * 569 * Return: Returns status, either success or error+reason 570 */ 571 static int zynqmp_pm_reset_get_status(const enum zynqmp_pm_reset reset, 572 u32 *status) 573 { 574 u32 ret_payload[PAYLOAD_ARG_CNT]; 575 int ret; 576 577 if (!status) 578 return -EINVAL; 579 580 ret = zynqmp_pm_invoke_fn(PM_RESET_GET_STATUS, reset, 0, 581 0, 0, ret_payload); 582 *status = ret_payload[1]; 583 584 return ret; 585 } 586 587 /** 588 * zynqmp_pm_fpga_load - Perform the fpga load 589 * @address: Address to write to 590 * @size: pl bitstream size 591 * @flags: Bitstream type 592 * -XILINX_ZYNQMP_PM_FPGA_FULL: FPGA full reconfiguration 593 * -XILINX_ZYNQMP_PM_FPGA_PARTIAL: FPGA partial reconfiguration 594 * 595 * This function provides access to pmufw. To transfer 596 * the required bitstream into PL. 597 * 598 * Return: Returns status, either success or error+reason 599 */ 600 static int zynqmp_pm_fpga_load(const u64 address, const u32 size, 601 const u32 flags) 602 { 603 return zynqmp_pm_invoke_fn(PM_FPGA_LOAD, lower_32_bits(address), 604 upper_32_bits(address), size, flags, NULL); 605 } 606 607 /** 608 * zynqmp_pm_fpga_get_status - Read value from PCAP status register 609 * @value: Value to read 610 * 611 * This function provides access to the pmufw to get the PCAP 612 * status 613 * 614 * Return: Returns status, either success or error+reason 615 */ 616 static int zynqmp_pm_fpga_get_status(u32 *value) 617 { 618 u32 ret_payload[PAYLOAD_ARG_CNT]; 619 int ret; 620 621 if (!value) 622 return -EINVAL; 623 624 ret = zynqmp_pm_invoke_fn(PM_FPGA_GET_STATUS, 0, 0, 0, 0, ret_payload); 625 *value = ret_payload[1]; 626 627 return ret; 628 } 629 630 /** 631 * zynqmp_pm_init_finalize() - PM call to inform firmware that the caller 632 * master has initialized its own power management 633 * 634 * This API function is to be used for notify the power management controller 635 * about the completed power management initialization. 636 * 637 * Return: Returns status, either success or error+reason 638 */ 639 static int zynqmp_pm_init_finalize(void) 640 { 641 return zynqmp_pm_invoke_fn(PM_PM_INIT_FINALIZE, 0, 0, 0, 0, NULL); 642 } 643 644 /** 645 * zynqmp_pm_set_suspend_mode() - Set system suspend mode 646 * @mode: Mode to set for system suspend 647 * 648 * This API function is used to set mode of system suspend. 649 * 650 * Return: Returns status, either success or error+reason 651 */ 652 static int zynqmp_pm_set_suspend_mode(u32 mode) 653 { 654 return zynqmp_pm_invoke_fn(PM_SET_SUSPEND_MODE, mode, 0, 0, 0, NULL); 655 } 656 657 /** 658 * zynqmp_pm_request_node() - Request a node with specific capabilities 659 * @node: Node ID of the slave 660 * @capabilities: Requested capabilities of the slave 661 * @qos: Quality of service (not supported) 662 * @ack: Flag to specify whether acknowledge is requested 663 * 664 * This function is used by master to request particular node from firmware. 665 * Every master must request node before using it. 666 * 667 * Return: Returns status, either success or error+reason 668 */ 669 static int zynqmp_pm_request_node(const u32 node, const u32 capabilities, 670 const u32 qos, 671 const enum zynqmp_pm_request_ack ack) 672 { 673 return zynqmp_pm_invoke_fn(PM_REQUEST_NODE, node, capabilities, 674 qos, ack, NULL); 675 } 676 677 /** 678 * zynqmp_pm_release_node() - Release a node 679 * @node: Node ID of the slave 680 * 681 * This function is used by master to inform firmware that master 682 * has released node. Once released, master must not use that node 683 * without re-request. 684 * 685 * Return: Returns status, either success or error+reason 686 */ 687 static int zynqmp_pm_release_node(const u32 node) 688 { 689 return zynqmp_pm_invoke_fn(PM_RELEASE_NODE, node, 0, 0, 0, NULL); 690 } 691 692 /** 693 * zynqmp_pm_set_requirement() - PM call to set requirement for PM slaves 694 * @node: Node ID of the slave 695 * @capabilities: Requested capabilities of the slave 696 * @qos: Quality of service (not supported) 697 * @ack: Flag to specify whether acknowledge is requested 698 * 699 * This API function is to be used for slaves a PU already has requested 700 * to change its capabilities. 701 * 702 * Return: Returns status, either success or error+reason 703 */ 704 static int zynqmp_pm_set_requirement(const u32 node, const u32 capabilities, 705 const u32 qos, 706 const enum zynqmp_pm_request_ack ack) 707 { 708 return zynqmp_pm_invoke_fn(PM_SET_REQUIREMENT, node, capabilities, 709 qos, ack, NULL); 710 } 711 712 /** 713 * zynqmp_pm_aes - Access AES hardware to encrypt/decrypt the data using 714 * AES-GCM core. 715 * @address: Address of the AesParams structure. 716 * @out: Returned output value 717 * 718 * Return: Returns status, either success or error code. 719 */ 720 static int zynqmp_pm_aes_engine(const u64 address, u32 *out) 721 { 722 u32 ret_payload[PAYLOAD_ARG_CNT]; 723 int ret; 724 725 if (!out) 726 return -EINVAL; 727 728 ret = zynqmp_pm_invoke_fn(PM_SECURE_AES, upper_32_bits(address), 729 lower_32_bits(address), 730 0, 0, ret_payload); 731 *out = ret_payload[1]; 732 733 return ret; 734 } 735 736 static const struct zynqmp_eemi_ops eemi_ops = { 737 .get_api_version = zynqmp_pm_get_api_version, 738 .get_chipid = zynqmp_pm_get_chipid, 739 .query_data = zynqmp_pm_query_data, 740 .clock_enable = zynqmp_pm_clock_enable, 741 .clock_disable = zynqmp_pm_clock_disable, 742 .clock_getstate = zynqmp_pm_clock_getstate, 743 .clock_setdivider = zynqmp_pm_clock_setdivider, 744 .clock_getdivider = zynqmp_pm_clock_getdivider, 745 .clock_setrate = zynqmp_pm_clock_setrate, 746 .clock_getrate = zynqmp_pm_clock_getrate, 747 .clock_setparent = zynqmp_pm_clock_setparent, 748 .clock_getparent = zynqmp_pm_clock_getparent, 749 .ioctl = zynqmp_pm_ioctl, 750 .reset_assert = zynqmp_pm_reset_assert, 751 .reset_get_status = zynqmp_pm_reset_get_status, 752 .init_finalize = zynqmp_pm_init_finalize, 753 .set_suspend_mode = zynqmp_pm_set_suspend_mode, 754 .request_node = zynqmp_pm_request_node, 755 .release_node = zynqmp_pm_release_node, 756 .set_requirement = zynqmp_pm_set_requirement, 757 .fpga_load = zynqmp_pm_fpga_load, 758 .fpga_get_status = zynqmp_pm_fpga_get_status, 759 .aes = zynqmp_pm_aes_engine, 760 }; 761 762 /** 763 * zynqmp_pm_get_eemi_ops - Get eemi ops functions 764 * 765 * Return: Pointer of eemi_ops structure 766 */ 767 const struct zynqmp_eemi_ops *zynqmp_pm_get_eemi_ops(void) 768 { 769 if (eemi_ops_tbl) 770 return eemi_ops_tbl; 771 else 772 return ERR_PTR(-EPROBE_DEFER); 773 774 } 775 EXPORT_SYMBOL_GPL(zynqmp_pm_get_eemi_ops); 776 777 static int zynqmp_firmware_probe(struct platform_device *pdev) 778 { 779 struct device *dev = &pdev->dev; 780 struct device_node *np; 781 int ret; 782 783 np = of_find_compatible_node(NULL, NULL, "xlnx,zynqmp"); 784 if (!np) { 785 np = of_find_compatible_node(NULL, NULL, "xlnx,versal"); 786 if (!np) 787 return 0; 788 789 feature_check_enabled = true; 790 } 791 of_node_put(np); 792 793 ret = get_set_conduit_method(dev->of_node); 794 if (ret) 795 return ret; 796 797 /* Check PM API version number */ 798 zynqmp_pm_get_api_version(&pm_api_version); 799 if (pm_api_version < ZYNQMP_PM_VERSION) { 800 panic("%s Platform Management API version error. Expected: v%d.%d - Found: v%d.%d\n", 801 __func__, 802 ZYNQMP_PM_VERSION_MAJOR, ZYNQMP_PM_VERSION_MINOR, 803 pm_api_version >> 16, pm_api_version & 0xFFFF); 804 } 805 806 pr_info("%s Platform Management API v%d.%d\n", __func__, 807 pm_api_version >> 16, pm_api_version & 0xFFFF); 808 809 /* Check trustzone version number */ 810 ret = zynqmp_pm_get_trustzone_version(&pm_tz_version); 811 if (ret) 812 panic("Legacy trustzone found without version support\n"); 813 814 if (pm_tz_version < ZYNQMP_TZ_VERSION) 815 panic("%s Trustzone version error. Expected: v%d.%d - Found: v%d.%d\n", 816 __func__, 817 ZYNQMP_TZ_VERSION_MAJOR, ZYNQMP_TZ_VERSION_MINOR, 818 pm_tz_version >> 16, pm_tz_version & 0xFFFF); 819 820 pr_info("%s Trustzone version v%d.%d\n", __func__, 821 pm_tz_version >> 16, pm_tz_version & 0xFFFF); 822 823 /* Assign eemi_ops_table */ 824 eemi_ops_tbl = &eemi_ops; 825 826 zynqmp_pm_api_debugfs_init(); 827 828 ret = mfd_add_devices(&pdev->dev, PLATFORM_DEVID_NONE, firmware_devs, 829 ARRAY_SIZE(firmware_devs), NULL, 0, NULL); 830 if (ret) { 831 dev_err(&pdev->dev, "failed to add MFD devices %d\n", ret); 832 return ret; 833 } 834 835 return of_platform_populate(dev->of_node, NULL, NULL, dev); 836 } 837 838 static int zynqmp_firmware_remove(struct platform_device *pdev) 839 { 840 mfd_remove_devices(&pdev->dev); 841 zynqmp_pm_api_debugfs_exit(); 842 843 return 0; 844 } 845 846 static const struct of_device_id zynqmp_firmware_of_match[] = { 847 {.compatible = "xlnx,zynqmp-firmware"}, 848 {.compatible = "xlnx,versal-firmware"}, 849 {}, 850 }; 851 MODULE_DEVICE_TABLE(of, zynqmp_firmware_of_match); 852 853 static struct platform_driver zynqmp_firmware_driver = { 854 .driver = { 855 .name = "zynqmp_firmware", 856 .of_match_table = zynqmp_firmware_of_match, 857 }, 858 .probe = zynqmp_firmware_probe, 859 .remove = zynqmp_firmware_remove, 860 }; 861 module_platform_driver(zynqmp_firmware_driver); 862