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_SET_PLL_FRAC_MODE: 516 case IOCTL_GET_PLL_FRAC_MODE: 517 case IOCTL_SET_PLL_FRAC_DATA: 518 case IOCTL_GET_PLL_FRAC_DATA: 519 return 1; 520 default: 521 return 0; 522 } 523 } 524 525 /** 526 * zynqmp_pm_ioctl() - PM IOCTL API for device control and configs 527 * @node_id: Node ID of the device 528 * @ioctl_id: ID of the requested IOCTL 529 * @arg1: Argument 1 to requested IOCTL call 530 * @arg2: Argument 2 to requested IOCTL call 531 * @out: Returned output value 532 * 533 * This function calls IOCTL to firmware for device control and configuration. 534 * 535 * Return: Returns status, either success or error+reason 536 */ 537 static int zynqmp_pm_ioctl(u32 node_id, u32 ioctl_id, u32 arg1, u32 arg2, 538 u32 *out) 539 { 540 if (!zynqmp_is_valid_ioctl(ioctl_id)) 541 return -EINVAL; 542 543 return zynqmp_pm_invoke_fn(PM_IOCTL, node_id, ioctl_id, 544 arg1, arg2, out); 545 } 546 547 /** 548 * zynqmp_pm_reset_assert - Request setting of reset (1 - assert, 0 - release) 549 * @reset: Reset to be configured 550 * @assert_flag: Flag stating should reset be asserted (1) or 551 * released (0) 552 * 553 * Return: Returns status, either success or error+reason 554 */ 555 static int zynqmp_pm_reset_assert(const enum zynqmp_pm_reset reset, 556 const enum zynqmp_pm_reset_action assert_flag) 557 { 558 return zynqmp_pm_invoke_fn(PM_RESET_ASSERT, reset, assert_flag, 559 0, 0, NULL); 560 } 561 562 /** 563 * zynqmp_pm_reset_get_status - Get status of the reset 564 * @reset: Reset whose status should be returned 565 * @status: Returned status 566 * 567 * Return: Returns status, either success or error+reason 568 */ 569 static int zynqmp_pm_reset_get_status(const enum zynqmp_pm_reset reset, 570 u32 *status) 571 { 572 u32 ret_payload[PAYLOAD_ARG_CNT]; 573 int ret; 574 575 if (!status) 576 return -EINVAL; 577 578 ret = zynqmp_pm_invoke_fn(PM_RESET_GET_STATUS, reset, 0, 579 0, 0, ret_payload); 580 *status = ret_payload[1]; 581 582 return ret; 583 } 584 585 /** 586 * zynqmp_pm_fpga_load - Perform the fpga load 587 * @address: Address to write to 588 * @size: pl bitstream size 589 * @flags: Bitstream type 590 * -XILINX_ZYNQMP_PM_FPGA_FULL: FPGA full reconfiguration 591 * -XILINX_ZYNQMP_PM_FPGA_PARTIAL: FPGA partial reconfiguration 592 * 593 * This function provides access to pmufw. To transfer 594 * the required bitstream into PL. 595 * 596 * Return: Returns status, either success or error+reason 597 */ 598 static int zynqmp_pm_fpga_load(const u64 address, const u32 size, 599 const u32 flags) 600 { 601 return zynqmp_pm_invoke_fn(PM_FPGA_LOAD, lower_32_bits(address), 602 upper_32_bits(address), size, flags, NULL); 603 } 604 605 /** 606 * zynqmp_pm_fpga_get_status - Read value from PCAP status register 607 * @value: Value to read 608 * 609 * This function provides access to the pmufw to get the PCAP 610 * status 611 * 612 * Return: Returns status, either success or error+reason 613 */ 614 static int zynqmp_pm_fpga_get_status(u32 *value) 615 { 616 u32 ret_payload[PAYLOAD_ARG_CNT]; 617 int ret; 618 619 if (!value) 620 return -EINVAL; 621 622 ret = zynqmp_pm_invoke_fn(PM_FPGA_GET_STATUS, 0, 0, 0, 0, ret_payload); 623 *value = ret_payload[1]; 624 625 return ret; 626 } 627 628 /** 629 * zynqmp_pm_init_finalize() - PM call to inform firmware that the caller 630 * master has initialized its own power management 631 * 632 * This API function is to be used for notify the power management controller 633 * about the completed power management initialization. 634 * 635 * Return: Returns status, either success or error+reason 636 */ 637 static int zynqmp_pm_init_finalize(void) 638 { 639 return zynqmp_pm_invoke_fn(PM_PM_INIT_FINALIZE, 0, 0, 0, 0, NULL); 640 } 641 642 /** 643 * zynqmp_pm_set_suspend_mode() - Set system suspend mode 644 * @mode: Mode to set for system suspend 645 * 646 * This API function is used to set mode of system suspend. 647 * 648 * Return: Returns status, either success or error+reason 649 */ 650 static int zynqmp_pm_set_suspend_mode(u32 mode) 651 { 652 return zynqmp_pm_invoke_fn(PM_SET_SUSPEND_MODE, mode, 0, 0, 0, NULL); 653 } 654 655 /** 656 * zynqmp_pm_request_node() - Request a node with specific capabilities 657 * @node: Node ID of the slave 658 * @capabilities: Requested capabilities of the slave 659 * @qos: Quality of service (not supported) 660 * @ack: Flag to specify whether acknowledge is requested 661 * 662 * This function is used by master to request particular node from firmware. 663 * Every master must request node before using it. 664 * 665 * Return: Returns status, either success or error+reason 666 */ 667 static int zynqmp_pm_request_node(const u32 node, const u32 capabilities, 668 const u32 qos, 669 const enum zynqmp_pm_request_ack ack) 670 { 671 return zynqmp_pm_invoke_fn(PM_REQUEST_NODE, node, capabilities, 672 qos, ack, NULL); 673 } 674 675 /** 676 * zynqmp_pm_release_node() - Release a node 677 * @node: Node ID of the slave 678 * 679 * This function is used by master to inform firmware that master 680 * has released node. Once released, master must not use that node 681 * without re-request. 682 * 683 * Return: Returns status, either success or error+reason 684 */ 685 static int zynqmp_pm_release_node(const u32 node) 686 { 687 return zynqmp_pm_invoke_fn(PM_RELEASE_NODE, node, 0, 0, 0, NULL); 688 } 689 690 /** 691 * zynqmp_pm_set_requirement() - PM call to set requirement for PM slaves 692 * @node: Node ID of the slave 693 * @capabilities: Requested capabilities of the slave 694 * @qos: Quality of service (not supported) 695 * @ack: Flag to specify whether acknowledge is requested 696 * 697 * This API function is to be used for slaves a PU already has requested 698 * to change its capabilities. 699 * 700 * Return: Returns status, either success or error+reason 701 */ 702 static int zynqmp_pm_set_requirement(const u32 node, const u32 capabilities, 703 const u32 qos, 704 const enum zynqmp_pm_request_ack ack) 705 { 706 return zynqmp_pm_invoke_fn(PM_SET_REQUIREMENT, node, capabilities, 707 qos, ack, NULL); 708 } 709 710 static const struct zynqmp_eemi_ops eemi_ops = { 711 .get_api_version = zynqmp_pm_get_api_version, 712 .get_chipid = zynqmp_pm_get_chipid, 713 .query_data = zynqmp_pm_query_data, 714 .clock_enable = zynqmp_pm_clock_enable, 715 .clock_disable = zynqmp_pm_clock_disable, 716 .clock_getstate = zynqmp_pm_clock_getstate, 717 .clock_setdivider = zynqmp_pm_clock_setdivider, 718 .clock_getdivider = zynqmp_pm_clock_getdivider, 719 .clock_setrate = zynqmp_pm_clock_setrate, 720 .clock_getrate = zynqmp_pm_clock_getrate, 721 .clock_setparent = zynqmp_pm_clock_setparent, 722 .clock_getparent = zynqmp_pm_clock_getparent, 723 .ioctl = zynqmp_pm_ioctl, 724 .reset_assert = zynqmp_pm_reset_assert, 725 .reset_get_status = zynqmp_pm_reset_get_status, 726 .init_finalize = zynqmp_pm_init_finalize, 727 .set_suspend_mode = zynqmp_pm_set_suspend_mode, 728 .request_node = zynqmp_pm_request_node, 729 .release_node = zynqmp_pm_release_node, 730 .set_requirement = zynqmp_pm_set_requirement, 731 .fpga_load = zynqmp_pm_fpga_load, 732 .fpga_get_status = zynqmp_pm_fpga_get_status, 733 }; 734 735 /** 736 * zynqmp_pm_get_eemi_ops - Get eemi ops functions 737 * 738 * Return: Pointer of eemi_ops structure 739 */ 740 const struct zynqmp_eemi_ops *zynqmp_pm_get_eemi_ops(void) 741 { 742 if (eemi_ops_tbl) 743 return eemi_ops_tbl; 744 else 745 return ERR_PTR(-EPROBE_DEFER); 746 747 } 748 EXPORT_SYMBOL_GPL(zynqmp_pm_get_eemi_ops); 749 750 static int zynqmp_firmware_probe(struct platform_device *pdev) 751 { 752 struct device *dev = &pdev->dev; 753 struct device_node *np; 754 int ret; 755 756 np = of_find_compatible_node(NULL, NULL, "xlnx,zynqmp"); 757 if (!np) { 758 np = of_find_compatible_node(NULL, NULL, "xlnx,versal"); 759 if (!np) 760 return 0; 761 762 feature_check_enabled = true; 763 } 764 of_node_put(np); 765 766 ret = get_set_conduit_method(dev->of_node); 767 if (ret) 768 return ret; 769 770 /* Check PM API version number */ 771 zynqmp_pm_get_api_version(&pm_api_version); 772 if (pm_api_version < ZYNQMP_PM_VERSION) { 773 panic("%s Platform Management API version error. Expected: v%d.%d - Found: v%d.%d\n", 774 __func__, 775 ZYNQMP_PM_VERSION_MAJOR, ZYNQMP_PM_VERSION_MINOR, 776 pm_api_version >> 16, pm_api_version & 0xFFFF); 777 } 778 779 pr_info("%s Platform Management API v%d.%d\n", __func__, 780 pm_api_version >> 16, pm_api_version & 0xFFFF); 781 782 /* Check trustzone version number */ 783 ret = zynqmp_pm_get_trustzone_version(&pm_tz_version); 784 if (ret) 785 panic("Legacy trustzone found without version support\n"); 786 787 if (pm_tz_version < ZYNQMP_TZ_VERSION) 788 panic("%s Trustzone version error. Expected: v%d.%d - Found: v%d.%d\n", 789 __func__, 790 ZYNQMP_TZ_VERSION_MAJOR, ZYNQMP_TZ_VERSION_MINOR, 791 pm_tz_version >> 16, pm_tz_version & 0xFFFF); 792 793 pr_info("%s Trustzone version v%d.%d\n", __func__, 794 pm_tz_version >> 16, pm_tz_version & 0xFFFF); 795 796 /* Assign eemi_ops_table */ 797 eemi_ops_tbl = &eemi_ops; 798 799 zynqmp_pm_api_debugfs_init(); 800 801 ret = mfd_add_devices(&pdev->dev, PLATFORM_DEVID_NONE, firmware_devs, 802 ARRAY_SIZE(firmware_devs), NULL, 0, NULL); 803 if (ret) { 804 dev_err(&pdev->dev, "failed to add MFD devices %d\n", ret); 805 return ret; 806 } 807 808 return of_platform_populate(dev->of_node, NULL, NULL, dev); 809 } 810 811 static int zynqmp_firmware_remove(struct platform_device *pdev) 812 { 813 mfd_remove_devices(&pdev->dev); 814 zynqmp_pm_api_debugfs_exit(); 815 816 return 0; 817 } 818 819 static const struct of_device_id zynqmp_firmware_of_match[] = { 820 {.compatible = "xlnx,zynqmp-firmware"}, 821 {.compatible = "xlnx,versal-firmware"}, 822 {}, 823 }; 824 MODULE_DEVICE_TABLE(of, zynqmp_firmware_of_match); 825 826 static struct platform_driver zynqmp_firmware_driver = { 827 .driver = { 828 .name = "zynqmp_firmware", 829 .of_match_table = zynqmp_firmware_of_match, 830 }, 831 .probe = zynqmp_firmware_probe, 832 .remove = zynqmp_firmware_remove, 833 }; 834 module_platform_driver(zynqmp_firmware_driver); 835