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