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_register_notifier() - PM API for register a subsystem 1135 * to be notified about specific 1136 * event/error. 1137 * @node: Node ID to which the event is related. 1138 * @event: Event Mask of Error events for which wants to get notified. 1139 * @wake: Wake subsystem upon capturing the event if value 1 1140 * @enable: Enable the registration for value 1, disable for value 0 1141 * 1142 * This function is used to register/un-register for particular node-event 1143 * combination in firmware. 1144 * 1145 * Return: Returns status, either success or error+reason 1146 */ 1147 1148 int zynqmp_pm_register_notifier(const u32 node, const u32 event, 1149 const u32 wake, const u32 enable) 1150 { 1151 return zynqmp_pm_invoke_fn(PM_REGISTER_NOTIFIER, node, event, 1152 wake, enable, NULL); 1153 } 1154 EXPORT_SYMBOL_GPL(zynqmp_pm_register_notifier); 1155 1156 /** 1157 * zynqmp_pm_system_shutdown - PM call to request a system shutdown or restart 1158 * @type: Shutdown or restart? 0 for shutdown, 1 for restart 1159 * @subtype: Specifies which system should be restarted or shut down 1160 * 1161 * Return: Returns status, either success or error+reason 1162 */ 1163 int zynqmp_pm_system_shutdown(const u32 type, const u32 subtype) 1164 { 1165 return zynqmp_pm_invoke_fn(PM_SYSTEM_SHUTDOWN, type, subtype, 1166 0, 0, NULL); 1167 } 1168 1169 /** 1170 * zynqmp_pm_set_feature_config - PM call to request IOCTL for feature config 1171 * @id: The config ID of the feature to be configured 1172 * @value: The config value of the feature to be configured 1173 * 1174 * Return: Returns 0 on success or error value on failure. 1175 */ 1176 int zynqmp_pm_set_feature_config(enum pm_feature_config_id id, u32 value) 1177 { 1178 return zynqmp_pm_invoke_fn(PM_IOCTL, 0, IOCTL_SET_FEATURE_CONFIG, 1179 id, value, NULL); 1180 } 1181 1182 /** 1183 * zynqmp_pm_get_feature_config - PM call to get value of configured feature 1184 * @id: The config id of the feature to be queried 1185 * @payload: Returned value array 1186 * 1187 * Return: Returns 0 on success or error value on failure. 1188 */ 1189 int zynqmp_pm_get_feature_config(enum pm_feature_config_id id, 1190 u32 *payload) 1191 { 1192 return zynqmp_pm_invoke_fn(PM_IOCTL, 0, IOCTL_GET_FEATURE_CONFIG, 1193 id, 0, payload); 1194 } 1195 1196 /** 1197 * struct zynqmp_pm_shutdown_scope - Struct for shutdown scope 1198 * @subtype: Shutdown subtype 1199 * @name: Matching string for scope argument 1200 * 1201 * This struct encapsulates mapping between shutdown scope ID and string. 1202 */ 1203 struct zynqmp_pm_shutdown_scope { 1204 const enum zynqmp_pm_shutdown_subtype subtype; 1205 const char *name; 1206 }; 1207 1208 static struct zynqmp_pm_shutdown_scope shutdown_scopes[] = { 1209 [ZYNQMP_PM_SHUTDOWN_SUBTYPE_SUBSYSTEM] = { 1210 .subtype = ZYNQMP_PM_SHUTDOWN_SUBTYPE_SUBSYSTEM, 1211 .name = "subsystem", 1212 }, 1213 [ZYNQMP_PM_SHUTDOWN_SUBTYPE_PS_ONLY] = { 1214 .subtype = ZYNQMP_PM_SHUTDOWN_SUBTYPE_PS_ONLY, 1215 .name = "ps_only", 1216 }, 1217 [ZYNQMP_PM_SHUTDOWN_SUBTYPE_SYSTEM] = { 1218 .subtype = ZYNQMP_PM_SHUTDOWN_SUBTYPE_SYSTEM, 1219 .name = "system", 1220 }, 1221 }; 1222 1223 static struct zynqmp_pm_shutdown_scope *selected_scope = 1224 &shutdown_scopes[ZYNQMP_PM_SHUTDOWN_SUBTYPE_SYSTEM]; 1225 1226 /** 1227 * zynqmp_pm_is_shutdown_scope_valid - Check if shutdown scope string is valid 1228 * @scope_string: Shutdown scope string 1229 * 1230 * Return: Return pointer to matching shutdown scope struct from 1231 * array of available options in system if string is valid, 1232 * otherwise returns NULL. 1233 */ 1234 static struct zynqmp_pm_shutdown_scope* 1235 zynqmp_pm_is_shutdown_scope_valid(const char *scope_string) 1236 { 1237 int count; 1238 1239 for (count = 0; count < ARRAY_SIZE(shutdown_scopes); count++) 1240 if (sysfs_streq(scope_string, shutdown_scopes[count].name)) 1241 return &shutdown_scopes[count]; 1242 1243 return NULL; 1244 } 1245 1246 static ssize_t shutdown_scope_show(struct device *device, 1247 struct device_attribute *attr, 1248 char *buf) 1249 { 1250 int i; 1251 1252 for (i = 0; i < ARRAY_SIZE(shutdown_scopes); i++) { 1253 if (&shutdown_scopes[i] == selected_scope) { 1254 strcat(buf, "["); 1255 strcat(buf, shutdown_scopes[i].name); 1256 strcat(buf, "]"); 1257 } else { 1258 strcat(buf, shutdown_scopes[i].name); 1259 } 1260 strcat(buf, " "); 1261 } 1262 strcat(buf, "\n"); 1263 1264 return strlen(buf); 1265 } 1266 1267 static ssize_t shutdown_scope_store(struct device *device, 1268 struct device_attribute *attr, 1269 const char *buf, size_t count) 1270 { 1271 int ret; 1272 struct zynqmp_pm_shutdown_scope *scope; 1273 1274 scope = zynqmp_pm_is_shutdown_scope_valid(buf); 1275 if (!scope) 1276 return -EINVAL; 1277 1278 ret = zynqmp_pm_system_shutdown(ZYNQMP_PM_SHUTDOWN_TYPE_SETSCOPE_ONLY, 1279 scope->subtype); 1280 if (ret) { 1281 pr_err("unable to set shutdown scope %s\n", buf); 1282 return ret; 1283 } 1284 1285 selected_scope = scope; 1286 1287 return count; 1288 } 1289 1290 static DEVICE_ATTR_RW(shutdown_scope); 1291 1292 static ssize_t health_status_store(struct device *device, 1293 struct device_attribute *attr, 1294 const char *buf, size_t count) 1295 { 1296 int ret; 1297 unsigned int value; 1298 1299 ret = kstrtouint(buf, 10, &value); 1300 if (ret) 1301 return ret; 1302 1303 ret = zynqmp_pm_set_boot_health_status(value); 1304 if (ret) { 1305 dev_err(device, "unable to set healthy bit value to %u\n", 1306 value); 1307 return ret; 1308 } 1309 1310 return count; 1311 } 1312 1313 static DEVICE_ATTR_WO(health_status); 1314 1315 static ssize_t ggs_show(struct device *device, 1316 struct device_attribute *attr, 1317 char *buf, 1318 u32 reg) 1319 { 1320 int ret; 1321 u32 ret_payload[PAYLOAD_ARG_CNT]; 1322 1323 ret = zynqmp_pm_read_ggs(reg, ret_payload); 1324 if (ret) 1325 return ret; 1326 1327 return sprintf(buf, "0x%x\n", ret_payload[1]); 1328 } 1329 1330 static ssize_t ggs_store(struct device *device, 1331 struct device_attribute *attr, 1332 const char *buf, size_t count, 1333 u32 reg) 1334 { 1335 long value; 1336 int ret; 1337 1338 if (reg >= GSS_NUM_REGS) 1339 return -EINVAL; 1340 1341 ret = kstrtol(buf, 16, &value); 1342 if (ret) { 1343 count = -EFAULT; 1344 goto err; 1345 } 1346 1347 ret = zynqmp_pm_write_ggs(reg, value); 1348 if (ret) 1349 count = -EFAULT; 1350 err: 1351 return count; 1352 } 1353 1354 /* GGS register show functions */ 1355 #define GGS0_SHOW(N) \ 1356 ssize_t ggs##N##_show(struct device *device, \ 1357 struct device_attribute *attr, \ 1358 char *buf) \ 1359 { \ 1360 return ggs_show(device, attr, buf, N); \ 1361 } 1362 1363 static GGS0_SHOW(0); 1364 static GGS0_SHOW(1); 1365 static GGS0_SHOW(2); 1366 static GGS0_SHOW(3); 1367 1368 /* GGS register store function */ 1369 #define GGS0_STORE(N) \ 1370 ssize_t ggs##N##_store(struct device *device, \ 1371 struct device_attribute *attr, \ 1372 const char *buf, \ 1373 size_t count) \ 1374 { \ 1375 return ggs_store(device, attr, buf, count, N); \ 1376 } 1377 1378 static GGS0_STORE(0); 1379 static GGS0_STORE(1); 1380 static GGS0_STORE(2); 1381 static GGS0_STORE(3); 1382 1383 static ssize_t pggs_show(struct device *device, 1384 struct device_attribute *attr, 1385 char *buf, 1386 u32 reg) 1387 { 1388 int ret; 1389 u32 ret_payload[PAYLOAD_ARG_CNT]; 1390 1391 ret = zynqmp_pm_read_pggs(reg, ret_payload); 1392 if (ret) 1393 return ret; 1394 1395 return sprintf(buf, "0x%x\n", ret_payload[1]); 1396 } 1397 1398 static ssize_t pggs_store(struct device *device, 1399 struct device_attribute *attr, 1400 const char *buf, size_t count, 1401 u32 reg) 1402 { 1403 long value; 1404 int ret; 1405 1406 if (reg >= GSS_NUM_REGS) 1407 return -EINVAL; 1408 1409 ret = kstrtol(buf, 16, &value); 1410 if (ret) { 1411 count = -EFAULT; 1412 goto err; 1413 } 1414 1415 ret = zynqmp_pm_write_pggs(reg, value); 1416 if (ret) 1417 count = -EFAULT; 1418 1419 err: 1420 return count; 1421 } 1422 1423 #define PGGS0_SHOW(N) \ 1424 ssize_t pggs##N##_show(struct device *device, \ 1425 struct device_attribute *attr, \ 1426 char *buf) \ 1427 { \ 1428 return pggs_show(device, attr, buf, N); \ 1429 } 1430 1431 #define PGGS0_STORE(N) \ 1432 ssize_t pggs##N##_store(struct device *device, \ 1433 struct device_attribute *attr, \ 1434 const char *buf, \ 1435 size_t count) \ 1436 { \ 1437 return pggs_store(device, attr, buf, count, N); \ 1438 } 1439 1440 /* PGGS register show functions */ 1441 static PGGS0_SHOW(0); 1442 static PGGS0_SHOW(1); 1443 static PGGS0_SHOW(2); 1444 static PGGS0_SHOW(3); 1445 1446 /* PGGS register store functions */ 1447 static PGGS0_STORE(0); 1448 static PGGS0_STORE(1); 1449 static PGGS0_STORE(2); 1450 static PGGS0_STORE(3); 1451 1452 /* GGS register attributes */ 1453 static DEVICE_ATTR_RW(ggs0); 1454 static DEVICE_ATTR_RW(ggs1); 1455 static DEVICE_ATTR_RW(ggs2); 1456 static DEVICE_ATTR_RW(ggs3); 1457 1458 /* PGGS register attributes */ 1459 static DEVICE_ATTR_RW(pggs0); 1460 static DEVICE_ATTR_RW(pggs1); 1461 static DEVICE_ATTR_RW(pggs2); 1462 static DEVICE_ATTR_RW(pggs3); 1463 1464 static ssize_t feature_config_id_show(struct device *device, 1465 struct device_attribute *attr, 1466 char *buf) 1467 { 1468 struct zynqmp_devinfo *devinfo = dev_get_drvdata(device); 1469 1470 return sysfs_emit(buf, "%d\n", devinfo->feature_conf_id); 1471 } 1472 1473 static ssize_t feature_config_id_store(struct device *device, 1474 struct device_attribute *attr, 1475 const char *buf, size_t count) 1476 { 1477 u32 config_id; 1478 int ret; 1479 struct zynqmp_devinfo *devinfo = dev_get_drvdata(device); 1480 1481 if (!buf) 1482 return -EINVAL; 1483 1484 ret = kstrtou32(buf, 10, &config_id); 1485 if (ret) 1486 return ret; 1487 1488 devinfo->feature_conf_id = config_id; 1489 1490 return count; 1491 } 1492 1493 static DEVICE_ATTR_RW(feature_config_id); 1494 1495 static ssize_t feature_config_value_show(struct device *device, 1496 struct device_attribute *attr, 1497 char *buf) 1498 { 1499 int ret; 1500 u32 ret_payload[PAYLOAD_ARG_CNT]; 1501 struct zynqmp_devinfo *devinfo = dev_get_drvdata(device); 1502 1503 ret = zynqmp_pm_get_feature_config(devinfo->feature_conf_id, 1504 ret_payload); 1505 if (ret) 1506 return ret; 1507 1508 return sysfs_emit(buf, "%d\n", ret_payload[1]); 1509 } 1510 1511 static ssize_t feature_config_value_store(struct device *device, 1512 struct device_attribute *attr, 1513 const char *buf, size_t count) 1514 { 1515 u32 value; 1516 int ret; 1517 struct zynqmp_devinfo *devinfo = dev_get_drvdata(device); 1518 1519 if (!buf) 1520 return -EINVAL; 1521 1522 ret = kstrtou32(buf, 10, &value); 1523 if (ret) 1524 return ret; 1525 1526 ret = zynqmp_pm_set_feature_config(devinfo->feature_conf_id, 1527 value); 1528 if (ret) 1529 return ret; 1530 1531 return count; 1532 } 1533 1534 static DEVICE_ATTR_RW(feature_config_value); 1535 1536 static struct attribute *zynqmp_firmware_attrs[] = { 1537 &dev_attr_ggs0.attr, 1538 &dev_attr_ggs1.attr, 1539 &dev_attr_ggs2.attr, 1540 &dev_attr_ggs3.attr, 1541 &dev_attr_pggs0.attr, 1542 &dev_attr_pggs1.attr, 1543 &dev_attr_pggs2.attr, 1544 &dev_attr_pggs3.attr, 1545 &dev_attr_shutdown_scope.attr, 1546 &dev_attr_health_status.attr, 1547 &dev_attr_feature_config_id.attr, 1548 &dev_attr_feature_config_value.attr, 1549 NULL, 1550 }; 1551 1552 ATTRIBUTE_GROUPS(zynqmp_firmware); 1553 1554 static int zynqmp_firmware_probe(struct platform_device *pdev) 1555 { 1556 struct device *dev = &pdev->dev; 1557 struct device_node *np; 1558 struct zynqmp_devinfo *devinfo; 1559 int ret; 1560 1561 np = of_find_compatible_node(NULL, NULL, "xlnx,zynqmp"); 1562 if (!np) { 1563 np = of_find_compatible_node(NULL, NULL, "xlnx,versal"); 1564 if (!np) 1565 return 0; 1566 1567 feature_check_enabled = true; 1568 } 1569 of_node_put(np); 1570 1571 ret = get_set_conduit_method(dev->of_node); 1572 if (ret) 1573 return ret; 1574 1575 devinfo = devm_kzalloc(dev, sizeof(*devinfo), GFP_KERNEL); 1576 if (!devinfo) 1577 return -ENOMEM; 1578 1579 devinfo->dev = dev; 1580 1581 platform_set_drvdata(pdev, devinfo); 1582 1583 /* Check PM API version number */ 1584 ret = zynqmp_pm_get_api_version(&pm_api_version); 1585 if (ret) 1586 return ret; 1587 1588 if (pm_api_version < ZYNQMP_PM_VERSION) { 1589 panic("%s Platform Management API version error. Expected: v%d.%d - Found: v%d.%d\n", 1590 __func__, 1591 ZYNQMP_PM_VERSION_MAJOR, ZYNQMP_PM_VERSION_MINOR, 1592 pm_api_version >> 16, pm_api_version & 0xFFFF); 1593 } 1594 1595 pr_info("%s Platform Management API v%d.%d\n", __func__, 1596 pm_api_version >> 16, pm_api_version & 0xFFFF); 1597 1598 /* Check trustzone version number */ 1599 ret = zynqmp_pm_get_trustzone_version(&pm_tz_version); 1600 if (ret) 1601 panic("Legacy trustzone found without version support\n"); 1602 1603 if (pm_tz_version < ZYNQMP_TZ_VERSION) 1604 panic("%s Trustzone version error. Expected: v%d.%d - Found: v%d.%d\n", 1605 __func__, 1606 ZYNQMP_TZ_VERSION_MAJOR, ZYNQMP_TZ_VERSION_MINOR, 1607 pm_tz_version >> 16, pm_tz_version & 0xFFFF); 1608 1609 pr_info("%s Trustzone version v%d.%d\n", __func__, 1610 pm_tz_version >> 16, pm_tz_version & 0xFFFF); 1611 1612 ret = mfd_add_devices(&pdev->dev, PLATFORM_DEVID_NONE, firmware_devs, 1613 ARRAY_SIZE(firmware_devs), NULL, 0, NULL); 1614 if (ret) { 1615 dev_err(&pdev->dev, "failed to add MFD devices %d\n", ret); 1616 return ret; 1617 } 1618 1619 zynqmp_pm_api_debugfs_init(); 1620 1621 np = of_find_compatible_node(NULL, NULL, "xlnx,versal"); 1622 if (np) { 1623 em_dev = platform_device_register_data(&pdev->dev, "xlnx_event_manager", 1624 -1, NULL, 0); 1625 if (IS_ERR(em_dev)) 1626 dev_err_probe(&pdev->dev, PTR_ERR(em_dev), "EM register fail with error\n"); 1627 } 1628 of_node_put(np); 1629 1630 return of_platform_populate(dev->of_node, NULL, NULL, dev); 1631 } 1632 1633 static int zynqmp_firmware_remove(struct platform_device *pdev) 1634 { 1635 struct pm_api_feature_data *feature_data; 1636 struct hlist_node *tmp; 1637 int i; 1638 1639 mfd_remove_devices(&pdev->dev); 1640 zynqmp_pm_api_debugfs_exit(); 1641 1642 hash_for_each_safe(pm_api_features_map, i, tmp, feature_data, hentry) { 1643 hash_del(&feature_data->hentry); 1644 kfree(feature_data); 1645 } 1646 1647 platform_device_unregister(em_dev); 1648 1649 return 0; 1650 } 1651 1652 static const struct of_device_id zynqmp_firmware_of_match[] = { 1653 {.compatible = "xlnx,zynqmp-firmware"}, 1654 {.compatible = "xlnx,versal-firmware"}, 1655 {}, 1656 }; 1657 MODULE_DEVICE_TABLE(of, zynqmp_firmware_of_match); 1658 1659 static struct platform_driver zynqmp_firmware_driver = { 1660 .driver = { 1661 .name = "zynqmp_firmware", 1662 .of_match_table = zynqmp_firmware_of_match, 1663 .dev_groups = zynqmp_firmware_groups, 1664 }, 1665 .probe = zynqmp_firmware_probe, 1666 .remove = zynqmp_firmware_remove, 1667 }; 1668 module_platform_driver(zynqmp_firmware_driver); 1669